﻿
# Endowment has two permanent body measurements: length and girth. Category/index are derived display
# state and are synchronized from that pair. Legacy category locks remain only as compatibility mirrors;
# they are never authoritative.
domcom_restore_locked_endowment_category_effect = {
    if = { limit = { var:domcom_locked_endowment_category = flag:micro } set_variable = { name = domcom_endowment_category value = flag:micro } }
    else_if = { limit = { var:domcom_locked_endowment_category = flag:small } set_variable = { name = domcom_endowment_category value = flag:small } }
    else_if = { limit = { var:domcom_locked_endowment_category = flag:average } set_variable = { name = domcom_endowment_category value = flag:average } }
    else_if = { limit = { var:domcom_locked_endowment_category = flag:big } set_variable = { name = domcom_endowment_category value = flag:big } }
    else_if = { limit = { var:domcom_locked_endowment_category = flag:hung } set_variable = { name = domcom_endowment_category value = flag:hung } }
    else_if = { limit = { var:domcom_locked_endowment_category = flag:massive } set_variable = { name = domcom_endowment_category value = flag:massive } }
}

domcom_lock_current_endowment_category_effect = {
    if = { limit = { var:domcom_endowment_category = flag:micro } set_variable = { name = domcom_locked_endowment_category value = flag:micro } }
    else_if = { limit = { var:domcom_endowment_category = flag:small } set_variable = { name = domcom_locked_endowment_category value = flag:small } }
    else_if = { limit = { var:domcom_endowment_category = flag:average } set_variable = { name = domcom_locked_endowment_category value = flag:average } }
    else_if = { limit = { var:domcom_endowment_category = flag:big } set_variable = { name = domcom_locked_endowment_category value = flag:big } }
    else_if = { limit = { var:domcom_endowment_category = flag:hung } set_variable = { name = domcom_locked_endowment_category value = flag:hung } }
    else_if = { limit = { var:domcom_endowment_category = flag:massive } set_variable = { name = domcom_locked_endowment_category value = flag:massive } }
}


# v1.10.2 hard invariant: once an adult male has a complete Endowment profile, the first complete
# measurement pair becomes the canonical body record. Ordinary interactions, failed checks, profile
# initialization, compatibility bridges, and display refreshes may mirror from it but may never replace it.
# Only the explicitly destructive Reroll Endowments tool clears these canonical values.
domcom_restore_canonical_endowment_effect = {
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 }

        # New saves / already-migrated saves: canonical measurements win unconditionally.
        if = {
            limit = {
                has_variable = domcom_canonical_length_tenths
                has_variable = domcom_canonical_girth_tenths
            }
            set_variable = { name = domcom_length_tenths value = var:domcom_canonical_length_tenths }
            set_variable = { name = domcom_girth_tenths value = var:domcom_canonical_girth_tenths }
            set_variable = { name = domcom_locked_length_tenths value = var:domcom_canonical_length_tenths }
            set_variable = { name = domcom_locked_girth_tenths value = var:domcom_canonical_girth_tenths }
            add_character_flag = domcom_endowment_locked
        }
        # Existing v1.9/v1.10 saves: the previous permanent lock is authoritative for migration.
        else_if = {
            limit = {
                has_variable = domcom_locked_length_tenths
                has_variable = domcom_locked_girth_tenths
            }
            set_variable = { name = domcom_canonical_length_tenths value = var:domcom_locked_length_tenths }
            set_variable = { name = domcom_canonical_girth_tenths value = var:domcom_locked_girth_tenths }
            set_variable = { name = domcom_length_tenths value = var:domcom_locked_length_tenths }
            set_variable = { name = domcom_girth_tenths value = var:domcom_locked_girth_tenths }
            add_character_flag = domcom_endowment_locked
        }
        # Legacy/partial saves: if a complete displayed pair exists but no lock does, preserve what the
        # player currently sees rather than generating a fresh body on the next interaction.
        else_if = {
            limit = {
                has_variable = domcom_length_tenths
                has_variable = domcom_girth_tenths
            }
            set_variable = { name = domcom_canonical_length_tenths value = var:domcom_length_tenths }
            set_variable = { name = domcom_canonical_girth_tenths value = var:domcom_girth_tenths }
            set_variable = { name = domcom_locked_length_tenths value = var:domcom_length_tenths }
            set_variable = { name = domcom_locked_girth_tenths value = var:domcom_girth_tenths }
            add_character_flag = domcom_endowment_locked
        }
    }
}

domcom_assign_endowment_effect = {
    domcom_restore_canonical_endowment_effect = yes
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            has_variable = domcom_locked_length_tenths
            has_variable = domcom_locked_girth_tenths
        }
        set_variable = { name = domcom_length_tenths value = var:domcom_locked_length_tenths }
        set_variable = { name = domcom_girth_tenths value = var:domcom_locked_girth_tenths }
    }
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 has_variable = domcom_locked_length_tenths NOT = { has_variable = domcom_locked_girth_tenths } }
        set_variable = { name = domcom_length_tenths value = var:domcom_locked_length_tenths }
    }
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 has_variable = domcom_locked_girth_tenths NOT = { has_variable = domcom_locked_length_tenths } }
        set_variable = { name = domcom_girth_tenths value = var:domcom_locked_girth_tenths }
    }

    # Ruler Designer future-body choice is authoritative, including choices made for child rulers.
    # It seeds measurements inside the selected tier once the character reaches 18.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            has_variable = domcom_designer_endowment_choice
            NOT = { has_variable = domcom_locked_length_tenths }
            NOT = { has_variable = domcom_locked_girth_tenths }
            NOT = { has_variable = domcom_length_tenths }
            NOT = { has_variable = domcom_girth_tenths }
        }
        domcom_seed_endowment_from_designer_choice_effect = yes
    }

    # Give an already-present compatibility source one chance to seed a brand new profile. This never
    # runs once Dominion has a locked measurement pair.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_locked_length_tenths }
            NOT = { has_variable = domcom_locked_girth_tenths }
            NOT = { has_variable = domcom_length_tenths }
            NOT = { has_variable = domcom_girth_tenths }
        }
        domcom_preseed_endowment_effect = yes
    }

    domcom_capture_endowment_heredity_effect = yes

    # Sons take one profile-level inheritance branch. Half use the sire-derived regression/variation path;
    # half ignore the sire seed and receive a completely fresh roll from the ordinary population curve.
    # Length and girth always take the same branch so one profile cannot be half inherited and half fresh.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_length_tenths }
            NOT = { has_variable = domcom_girth_tenths }
            has_variable = domcom_sire_length_tenths
            has_variable = domcom_sire_girth_tenths
        }
        random = {
            chance = 50
            add_character_flag = domcom_use_sire_endowment_roll
        }
    }

    # Sired roll. The inherited half still uses regression toward the mean plus variation; it never copies
    # the father's exact stored measurements.
    # over several generations but does not lock itself there, and no single birth is a copy of the
    # father.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_length_tenths }
            has_character_flag = domcom_use_sire_endowment_roll
            has_variable = domcom_sire_length_tenths
        }
        set_variable = { name = domcom_length_tenths value = domcom_sire_length_seed_value }
        random_list = {
            3  = { change_variable = { name = domcom_length_tenths add = -8 } }
            7  = { change_variable = { name = domcom_length_tenths add = -6 } }
            12 = { change_variable = { name = domcom_length_tenths add = -4 } }
            18 = { change_variable = { name = domcom_length_tenths add = -2 } }
            20 = { change_variable = { name = domcom_length_tenths add = 0 } }
            18 = { change_variable = { name = domcom_length_tenths add = 2 } }
            12 = { change_variable = { name = domcom_length_tenths add = 4 } }
            7  = { change_variable = { name = domcom_length_tenths add = 6 } }
            3  = { change_variable = { name = domcom_length_tenths add = 8 } }
        }
        if = { limit = { var:domcom_length_tenths < 15 } set_variable = { name = domcom_length_tenths value = 15 } }
        if = { limit = { var:domcom_length_tenths > 130 } set_variable = { name = domcom_length_tenths value = 130 } }
    }
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_girth_tenths }
            has_character_flag = domcom_use_sire_endowment_roll
            has_variable = domcom_sire_girth_tenths
        }
        set_variable = { name = domcom_girth_tenths value = domcom_sire_girth_seed_value }
        random_list = {
            5  = { change_variable = { name = domcom_girth_tenths add = -6 } }
            10 = { change_variable = { name = domcom_girth_tenths add = -4 } }
            20 = { change_variable = { name = domcom_girth_tenths add = -2 } }
            30 = { change_variable = { name = domcom_girth_tenths add = 0 } }
            20 = { change_variable = { name = domcom_girth_tenths add = 2 } }
            10 = { change_variable = { name = domcom_girth_tenths add = 4 } }
            5  = { change_variable = { name = domcom_girth_tenths add = 6 } }
        }
        if = { limit = { var:domcom_girth_tenths < 20 } set_variable = { name = domcom_girth_tenths value = 20 } }
        if = { limit = { var:domcom_girth_tenths > 85 } set_variable = { name = domcom_girth_tenths value = 85 } }
    }

    # v2.5.6 population curve: tier-first bell curve, shifted modestly lower and widened so Average/Big
    # no longer consume nearly the entire adult population. The weights approximate a broad normal curve
    # centered around the low-5-inch range while keeping clinically tiny and extreme Massive bodies rare.
    # Fresh profiles: ~0.6% Micro / 20.6% Small / 54.6% Average / 19.7% Big / 4.4% Hung / 0.1% Massive.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_length_tenths }
            NOT = { has_variable = domcom_girth_tenths }
        }
        random_list = {
            6   = { domcom_seed_tier_micro_effect = yes }
            206 = { domcom_seed_tier_small_effect = yes }
            546 = { domcom_seed_tier_average_effect = yes }
            197 = { domcom_seed_tier_big_effect = yes }
            44  = { domcom_seed_tier_hung_effect = yes }
            1   = { domcom_seed_tier_massive_effect = yes }
        }
    }

    # Partial legacy profiles can still be missing only one measurement; preserve the fallback curve below
    # for those repair cases rather than discarding the surviving measurement.
    # v2.3.4 population curve: centered near 5.4 in length and 4.7 in girth. Extreme tails remain
    # possible for gameplay, but Micro and Massive bodies are genuinely rare rather than ordinary seeds.
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 NOT = { has_variable = domcom_length_tenths } }
        random_list = {
            1 = { set_variable = { name = domcom_length_tenths value = 15 } }
            2 = { set_variable = { name = domcom_length_tenths value = 20 } }
            4 = { set_variable = { name = domcom_length_tenths value = 25 } }
            8 = { set_variable = { name = domcom_length_tenths value = 30 } }
            20 = { set_variable = { name = domcom_length_tenths value = 35 } }
            50 = { set_variable = { name = domcom_length_tenths value = 40 } }
            80 = { set_variable = { name = domcom_length_tenths value = 42 } }
            180 = { set_variable = { name = domcom_length_tenths value = 45 } }
            350 = { set_variable = { name = domcom_length_tenths value = 48 } }
            700 = { set_variable = { name = domcom_length_tenths value = 50 } }
            1000 = { set_variable = { name = domcom_length_tenths value = 52 } }
            1200 = { set_variable = { name = domcom_length_tenths value = 53 } }
            1200 = { set_variable = { name = domcom_length_tenths value = 54 } }
            1100 = { set_variable = { name = domcom_length_tenths value = 55 } }
            800 = { set_variable = { name = domcom_length_tenths value = 57 } }
            500 = { set_variable = { name = domcom_length_tenths value = 60 } }
            250 = { set_variable = { name = domcom_length_tenths value = 62 } }
            120 = { set_variable = { name = domcom_length_tenths value = 65 } }
            70 = { set_variable = { name = domcom_length_tenths value = 67 } }
            35 = { set_variable = { name = domcom_length_tenths value = 70 } }
            12 = { set_variable = { name = domcom_length_tenths value = 75 } }
            5 = { set_variable = { name = domcom_length_tenths value = 80 } }
            2 = { set_variable = { name = domcom_length_tenths value = 85 } }
            1 = { set_variable = { name = domcom_length_tenths value = 90 } }
            1 = { set_variable = { name = domcom_length_tenths value = 100 } }
            1 = { set_variable = { name = domcom_length_tenths value = 110 } }
            1 = { set_variable = { name = domcom_length_tenths value = 130 } }
        }
    }
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 NOT = { has_variable = domcom_girth_tenths } }
        random_list = {
            1 = { set_variable = { name = domcom_girth_tenths value = 20 } }
            2 = { set_variable = { name = domcom_girth_tenths value = 25 } }
            5 = { set_variable = { name = domcom_girth_tenths value = 30 } }
            20 = { set_variable = { name = domcom_girth_tenths value = 35 } }
            60 = { set_variable = { name = domcom_girth_tenths value = 38 } }
            180 = { set_variable = { name = domcom_girth_tenths value = 40 } }
            400 = { set_variable = { name = domcom_girth_tenths value = 42 } }
            800 = { set_variable = { name = domcom_girth_tenths value = 44 } }
            1200 = { set_variable = { name = domcom_girth_tenths value = 46 } }
            1300 = { set_variable = { name = domcom_girth_tenths value = 47 } }
            1200 = { set_variable = { name = domcom_girth_tenths value = 48 } }
            900 = { set_variable = { name = domcom_girth_tenths value = 50 } }
            500 = { set_variable = { name = domcom_girth_tenths value = 52 } }
            250 = { set_variable = { name = domcom_girth_tenths value = 55 } }
            100 = { set_variable = { name = domcom_girth_tenths value = 58 } }
            50 = { set_variable = { name = domcom_girth_tenths value = 60 } }
            15 = { set_variable = { name = domcom_girth_tenths value = 65 } }
            5 = { set_variable = { name = domcom_girth_tenths value = 70 } }
            2 = { set_variable = { name = domcom_girth_tenths value = 75 } }
            1 = { set_variable = { name = domcom_girth_tenths value = 85 } }
        }
    }

    # The branch flag is only needed during this assignment pass.
    remove_character_flag = domcom_use_sire_endowment_roll

    # Adopt the first complete pair as the permanent profile. This also migrates existing saves without
    # changing their current measurements.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            has_variable = domcom_length_tenths
            has_variable = domcom_girth_tenths
            OR = {
                NOT = { has_variable = domcom_locked_length_tenths }
                NOT = { has_variable = domcom_locked_girth_tenths }
            }
        }
        if = { limit = { NOT = { has_variable = domcom_locked_length_tenths } } set_variable = { name = domcom_locked_length_tenths value = var:domcom_length_tenths } }
        if = { limit = { NOT = { has_variable = domcom_locked_girth_tenths } } set_variable = { name = domcom_locked_girth_tenths value = var:domcom_girth_tenths } }
        add_character_flag = domcom_endowment_locked
    }

    # Commit a brand-new complete roll to the canonical record, or restore an existing canonical pair
    # before any display/category work.
    domcom_restore_canonical_endowment_effect = yes

    # Restore the permanent measurements before display work. Measurements are the authoritative state;
    # the visible tier is derived deterministically every time from that locked pair. This prevents an old
    # or compatibility-seeded category lock from drifting out of sync (for example 13.0 x 5.0 displaying
    # as Small) while still guaranteeing that ordinary profile refreshes never reroll the body itself.
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes age >= 18
            has_variable = domcom_locked_length_tenths
            has_variable = domcom_locked_girth_tenths
        }
        set_variable = { name = domcom_length_tenths value = var:domcom_locked_length_tenths }
        set_variable = { name = domcom_girth_tenths value = var:domcom_locked_girth_tenths }
        domcom_sync_endowment_trait_effect = yes
    }


    if = {
        limit = {
            age >= 18
            has_variable = domcom_canonical_length_tenths
            has_variable = domcom_canonical_girth_tenths
            has_variable = domcom_designer_endowment_choice
        }
        remove_variable = domcom_designer_endowment_choice
    }

    # v1.6 Endowment Registry: profiles are indexed once when they exist. The GUI can therefore sort the
    # world without re-running profile assignment or scanning every character on every click.
    if = {
        limit = {
            is_alive = yes domcom_should_express_endowment_trigger = yes age >= 18
            has_variable = domcom_length_tenths
            has_variable = domcom_girth_tenths
            NOT = { is_target_in_global_variable_list = { name = domcom_all_endowments target = this } }
        }
        add_to_global_variable_list = { name = domcom_all_endowments target = this }
    }
}

# Converts the hidden measurements into one visible physical trait. This is run even for old saves so the
# former character-modifier display migrates cleanly.
domcom_sync_endowment_trait_effect = {
    domcom_restore_canonical_endowment_effect = yes
    if = {
        limit = { domcom_should_express_endowment_trigger = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths }

        if = { limit = { has_character_modifier = domcom_endowment_modest_modifier } remove_character_modifier = domcom_endowment_modest_modifier }
        if = { limit = { has_character_modifier = domcom_endowment_average_modifier } remove_character_modifier = domcom_endowment_average_modifier }
        if = { limit = { has_character_modifier = domcom_endowment_noteworthy_modifier } remove_character_modifier = domcom_endowment_noteworthy_modifier }
        if = { limit = { has_character_modifier = domcom_endowment_enviable_modifier } remove_character_modifier = domcom_endowment_enviable_modifier }
        if = { limit = { has_character_modifier = domcom_endowment_legendary_modifier } remove_character_modifier = domcom_endowment_legendary_modifier }

        # v2.3.4: human-readable Endowment bands. Length establishes the base descriptor; girth can
        # promote that descriptor by at most one tier, but never demote it. Micropenis is a hard two-part
        # gate: no character may receive the label above 2.5 in length or above 3.5 in girth. The stored
        # measurement grid is tenths, so the requested 4.25 in Small boundary means 4.2 is the last
        # generated Small length and 4.3 is the first Average length.
        #
        # Base length bands: <=2.5 Micro, 2.6-4.2 Small, 4.3-5.7 Average, 5.8-6.7 Big,
        # 6.8-8.2 Hung, >=8.3 Massive. Girth promotion ceilings: 3.5 / 5.0 / 5.5 / 6.0 / 7.0.
        # v2.5.1: the old Combined Endowment index is retired. Length/girth remain authoritative.
        if = { limit = { has_variable = domcom_endowment_index } remove_variable = domcom_endowment_index }

        if = {
            limit = { var:domcom_length_tenths <= 25 }
            if = { limit = { var:domcom_girth_tenths <= 35 } set_variable = { name = domcom_endowment_category value = flag:micro } }
            else = { set_variable = { name = domcom_endowment_category value = flag:small } }
        }
        else_if = {
            limit = { var:domcom_length_tenths < 43 }
            if = { limit = { var:domcom_girth_tenths > 50 } set_variable = { name = domcom_endowment_category value = flag:average } }
            else = { set_variable = { name = domcom_endowment_category value = flag:small } }
        }
        else_if = {
            limit = { var:domcom_length_tenths < 58 }
            if = { limit = { var:domcom_girth_tenths > 55 } set_variable = { name = domcom_endowment_category value = flag:big } }
            else = { set_variable = { name = domcom_endowment_category value = flag:average } }
        }
        else_if = {
            limit = { var:domcom_length_tenths < 68 }
            if = { limit = { var:domcom_girth_tenths > 60 } set_variable = { name = domcom_endowment_category value = flag:hung } }
            else = { set_variable = { name = domcom_endowment_category value = flag:big } }
        }
        else_if = {
            limit = { var:domcom_length_tenths < 83 }
            if = { limit = { var:domcom_girth_tenths > 70 } set_variable = { name = domcom_endowment_category value = flag:massive } }
            else = { set_variable = { name = domcom_endowment_category value = flag:hung } }
        }
        else = { set_variable = { name = domcom_endowment_category value = flag:massive } }

        # Keep the legacy lock variable synchronized for save/compatibility consumers, but it is no longer
        # authoritative. The permanent measurement pair above is the single source of truth.
        remove_variable = domcom_locked_endowment_category
        domcom_lock_current_endowment_category_effect = yes

        # Give an optional external anatomy bridge the first chance to establish/repair its visible
        # body trait. The native trait is removed only after the replacement is actually present.
        # This makes the handoff transactional: a failed external seed can never leave the character
        # with neither system visible.
        domcom_external_endowment_body_sync_effect = yes

        # Base Dominion owns the visible Endowment trait unless the external bridge confirms that its
        # replacement is active. Hidden measurements and Mastery remain available either way.
        if = {
            limit = { NOT = { domcom_external_replaces_endowment_trait_trigger = yes } }
            domcom_apply_native_endowment_trait_effect = yes
        }
        else = { domcom_clear_endowment_traits_effect = yes }

        domcom_post_category_effect = yes
    }
}


domcom_seed_tier_micro_effect = {
    random_list = {
        5  = { set_variable = { name = domcom_length_tenths value = 15 } set_variable = { name = domcom_girth_tenths value = 25 } }
        20 = { set_variable = { name = domcom_length_tenths value = 20 } set_variable = { name = domcom_girth_tenths value = 25 } }
        30 = { set_variable = { name = domcom_length_tenths value = 20 } set_variable = { name = domcom_girth_tenths value = 30 } }
        25 = { set_variable = { name = domcom_length_tenths value = 25 } set_variable = { name = domcom_girth_tenths value = 30 } }
        20 = { set_variable = { name = domcom_length_tenths value = 25 } set_variable = { name = domcom_girth_tenths value = 35 } }
    }
}

domcom_seed_tier_small_effect = {
    random_list = {
        10 = { set_variable = { name = domcom_length_tenths value = 30 } set_variable = { name = domcom_girth_tenths value = 35 } }
        20 = { set_variable = { name = domcom_length_tenths value = 35 } set_variable = { name = domcom_girth_tenths value = 40 } }
        30 = { set_variable = { name = domcom_length_tenths value = 40 } set_variable = { name = domcom_girth_tenths value = 42 } }
        25 = { set_variable = { name = domcom_length_tenths value = 42 } set_variable = { name = domcom_girth_tenths value = 45 } }
        15 = { set_variable = { name = domcom_length_tenths value = 42 } set_variable = { name = domcom_girth_tenths value = 50 } }
    }
}

domcom_seed_tier_average_effect = {
    random_list = {
        15 = { set_variable = { name = domcom_length_tenths value = 45 } set_variable = { name = domcom_girth_tenths value = 40 } }
        20 = { set_variable = { name = domcom_length_tenths value = 50 } set_variable = { name = domcom_girth_tenths value = 44 } }
        30 = { set_variable = { name = domcom_length_tenths value = 53 } set_variable = { name = domcom_girth_tenths value = 47 } }
        20 = { set_variable = { name = domcom_length_tenths value = 55 } set_variable = { name = domcom_girth_tenths value = 50 } }
        15 = { set_variable = { name = domcom_length_tenths value = 57 } set_variable = { name = domcom_girth_tenths value = 55 } }
    }
}

domcom_seed_tier_big_effect = {
    random_list = {
        15 = { set_variable = { name = domcom_length_tenths value = 58 } set_variable = { name = domcom_girth_tenths value = 50 } }
        20 = { set_variable = { name = domcom_length_tenths value = 60 } set_variable = { name = domcom_girth_tenths value = 52 } }
        30 = { set_variable = { name = domcom_length_tenths value = 63 } set_variable = { name = domcom_girth_tenths value = 54 } }
        20 = { set_variable = { name = domcom_length_tenths value = 65 } set_variable = { name = domcom_girth_tenths value = 56 } }
        15 = { set_variable = { name = domcom_length_tenths value = 67 } set_variable = { name = domcom_girth_tenths value = 60 } }
    }
}

domcom_seed_tier_hung_effect = {
    random_list = {
        20 = { set_variable = { name = domcom_length_tenths value = 68 } set_variable = { name = domcom_girth_tenths value = 53 } }
        25 = { set_variable = { name = domcom_length_tenths value = 70 } set_variable = { name = domcom_girth_tenths value = 55 } }
        25 = { set_variable = { name = domcom_length_tenths value = 75 } set_variable = { name = domcom_girth_tenths value = 58 } }
        20 = { set_variable = { name = domcom_length_tenths value = 80 } set_variable = { name = domcom_girth_tenths value = 62 } }
        10 = { set_variable = { name = domcom_length_tenths value = 82 } set_variable = { name = domcom_girth_tenths value = 70 } }
    }
}

domcom_seed_tier_massive_effect = {
    random_list = {
        25 = { set_variable = { name = domcom_length_tenths value = 83 } set_variable = { name = domcom_girth_tenths value = 60 } }
        25 = { set_variable = { name = domcom_length_tenths value = 85 } set_variable = { name = domcom_girth_tenths value = 65 } }
        20 = { set_variable = { name = domcom_length_tenths value = 90 } set_variable = { name = domcom_girth_tenths value = 65 } }
        15 = { set_variable = { name = domcom_length_tenths value = 100 } set_variable = { name = domcom_girth_tenths value = 70 } }
        10 = { set_variable = { name = domcom_length_tenths value = 110 } set_variable = { name = domcom_girth_tenths value = 75 } }
        5  = { set_variable = { name = domcom_length_tenths value = 130 } set_variable = { name = domcom_girth_tenths value = 85 } }
    }
}

# Reads a Dominion Endowment trait the character is already carrying and seeds from it. Used by the
# standalone preseed and, as a fallback, by the Carnalitas one. Highest tier wins if a designer somehow
# produced more than one.
domcom_seed_from_own_trait_effect = {
    if = { limit = { has_trait = domcom_endowment_massive } domcom_seed_tier_massive_effect = yes }
    else_if = { limit = { has_trait = domcom_endowment_hung } domcom_seed_tier_hung_effect = yes }
    else_if = { limit = { has_trait = domcom_endowment_big } domcom_seed_tier_big_effect = yes }
    else_if = { limit = { has_trait = domcom_endowment_average } domcom_seed_tier_average_effect = yes }
    else_if = { limit = { has_trait = domcom_endowment_small } domcom_seed_tier_small_effect = yes }
    else_if = { limit = { has_trait = domcom_endowment_micro } domcom_seed_tier_micro_effect = yes }
}


domcom_deactivate_endowment_traits_effect = {
    domcom_clear_endowment_traits_effect = yes
}

domcom_activate_endowment_traits_effect = {
    if = { limit = { has_inactive_trait = domcom_endowment_micro } make_trait_active = domcom_endowment_micro }
    if = { limit = { has_inactive_trait = domcom_endowment_small } make_trait_active = domcom_endowment_small }
    if = { limit = { has_inactive_trait = domcom_endowment_average } make_trait_active = domcom_endowment_average }
    if = { limit = { has_inactive_trait = domcom_endowment_big } make_trait_active = domcom_endowment_big }
    if = { limit = { has_inactive_trait = domcom_endowment_hung } make_trait_active = domcom_endowment_hung }
    if = { limit = { has_inactive_trait = domcom_endowment_massive } make_trait_active = domcom_endowment_massive }
}

# The sanity pass. Cheap, idempotent, and safe to run on anybody.
domcom_refresh_endowment_expression_effect = {
    # Repair/establish any external anatomy authority before deciding whether the native trait belongs.
    domcom_external_endowment_body_sync_effect = yes
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { domcom_external_replaces_endowment_trait_trigger = yes }
        }
        domcom_activate_endowment_traits_effect = yes
    }
    else = {
        domcom_deactivate_endowment_traits_effect = yes
    }
    domcom_carn_suppress_dt_traits_effect = yes
}

domcom_refresh_endowment_expression_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_endowment_expression_pass_101 } }
        every_living_character = {
            limit = {
                OR = {
                    has_trait = domcom_endowment_micro
                    has_trait = domcom_endowment_small
                    has_trait = domcom_endowment_average
                    has_trait = domcom_endowment_big
                    has_trait = domcom_endowment_hung
                    has_trait = domcom_endowment_massive
                }
                NOT = { domcom_should_express_endowment_trigger = yes }
            }
            domcom_deactivate_endowment_traits_effect = yes
        }
        set_global_variable = domcom_endowment_expression_pass_101
    }
}

domcom_clear_endowment_traits_effect = {
    if = { limit = { has_inactive_trait = domcom_endowment_micro } make_trait_active = domcom_endowment_micro }
    if = { limit = { has_inactive_trait = domcom_endowment_small } make_trait_active = domcom_endowment_small }
    if = { limit = { has_inactive_trait = domcom_endowment_average } make_trait_active = domcom_endowment_average }
    if = { limit = { has_inactive_trait = domcom_endowment_big } make_trait_active = domcom_endowment_big }
    if = { limit = { has_inactive_trait = domcom_endowment_hung } make_trait_active = domcom_endowment_hung }
    if = { limit = { has_inactive_trait = domcom_endowment_massive } make_trait_active = domcom_endowment_massive }
    if = { limit = { has_trait = domcom_endowment_micro } remove_trait = domcom_endowment_micro }
    if = { limit = { has_trait = domcom_endowment_small } remove_trait = domcom_endowment_small }
    if = { limit = { has_trait = domcom_endowment_average } remove_trait = domcom_endowment_average }
    if = { limit = { has_trait = domcom_endowment_big } remove_trait = domcom_endowment_big }
    if = { limit = { has_trait = domcom_endowment_hung } remove_trait = domcom_endowment_hung }
    if = { limit = { has_trait = domcom_endowment_massive } remove_trait = domcom_endowment_massive }
}

domcom_capture_endowment_heredity_effect = {
    if = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            NOT = { has_variable = domcom_sire_length_tenths }
        }
        if = {
            limit = {
                exists = real_father
                real_father = { has_variable = domcom_locked_length_tenths }
            }
            real_father = { save_temporary_scope_as = domcom_heredity_sire }
        }
        else_if = {
            limit = {
                exists = father
                father = { has_variable = domcom_locked_length_tenths }
            }
            father = { save_temporary_scope_as = domcom_heredity_sire }
        }
        if = {
            limit = { exists = scope:domcom_heredity_sire }
            set_variable = {
                name = domcom_sire_length_tenths
                value = scope:domcom_heredity_sire.var:domcom_locked_length_tenths
            }
            if = {
                limit = { scope:domcom_heredity_sire = { has_variable = domcom_locked_girth_tenths } }
                set_variable = {
                    name = domcom_sire_girth_tenths
                    value = scope:domcom_heredity_sire.var:domcom_locked_girth_tenths
                }
            }
        }
    }
}

domcom_seed_preference_micro_effect = {
    random_list = {
        5  = { set_variable = { name = domcom_pref_length_tenths value = 15 } set_variable = { name = domcom_pref_girth_tenths value = 25 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 20 } set_variable = { name = domcom_pref_girth_tenths value = 25 } }
        30 = { set_variable = { name = domcom_pref_length_tenths value = 20 } set_variable = { name = domcom_pref_girth_tenths value = 30 } }
        25 = { set_variable = { name = domcom_pref_length_tenths value = 25 } set_variable = { name = domcom_pref_girth_tenths value = 30 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 25 } set_variable = { name = domcom_pref_girth_tenths value = 35 } }
    }
}

domcom_seed_preference_small_effect = {
    random_list = {
        10 = { set_variable = { name = domcom_pref_length_tenths value = 30 } set_variable = { name = domcom_pref_girth_tenths value = 35 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 35 } set_variable = { name = domcom_pref_girth_tenths value = 40 } }
        30 = { set_variable = { name = domcom_pref_length_tenths value = 40 } set_variable = { name = domcom_pref_girth_tenths value = 42 } }
        25 = { set_variable = { name = domcom_pref_length_tenths value = 42 } set_variable = { name = domcom_pref_girth_tenths value = 45 } }
        15 = { set_variable = { name = domcom_pref_length_tenths value = 42 } set_variable = { name = domcom_pref_girth_tenths value = 50 } }
    }
}

domcom_seed_preference_average_effect = {
    random_list = {
        15 = { set_variable = { name = domcom_pref_length_tenths value = 45 } set_variable = { name = domcom_pref_girth_tenths value = 40 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 50 } set_variable = { name = domcom_pref_girth_tenths value = 44 } }
        30 = { set_variable = { name = domcom_pref_length_tenths value = 53 } set_variable = { name = domcom_pref_girth_tenths value = 47 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 55 } set_variable = { name = domcom_pref_girth_tenths value = 50 } }
        15 = { set_variable = { name = domcom_pref_length_tenths value = 57 } set_variable = { name = domcom_pref_girth_tenths value = 55 } }
    }
}

domcom_seed_preference_big_effect = {
    random_list = {
        15 = { set_variable = { name = domcom_pref_length_tenths value = 58 } set_variable = { name = domcom_pref_girth_tenths value = 50 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 60 } set_variable = { name = domcom_pref_girth_tenths value = 52 } }
        30 = { set_variable = { name = domcom_pref_length_tenths value = 63 } set_variable = { name = domcom_pref_girth_tenths value = 54 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 65 } set_variable = { name = domcom_pref_girth_tenths value = 56 } }
        15 = { set_variable = { name = domcom_pref_length_tenths value = 67 } set_variable = { name = domcom_pref_girth_tenths value = 60 } }
    }
}

domcom_seed_preference_hung_effect = {
    random_list = {
        20 = { set_variable = { name = domcom_pref_length_tenths value = 68 } set_variable = { name = domcom_pref_girth_tenths value = 53 } }
        25 = { set_variable = { name = domcom_pref_length_tenths value = 70 } set_variable = { name = domcom_pref_girth_tenths value = 55 } }
        25 = { set_variable = { name = domcom_pref_length_tenths value = 75 } set_variable = { name = domcom_pref_girth_tenths value = 58 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 80 } set_variable = { name = domcom_pref_girth_tenths value = 62 } }
        10 = { set_variable = { name = domcom_pref_length_tenths value = 82 } set_variable = { name = domcom_pref_girth_tenths value = 70 } }
    }
}

domcom_seed_preference_massive_effect = {
    random_list = {
        25 = { set_variable = { name = domcom_pref_length_tenths value = 83 } set_variable = { name = domcom_pref_girth_tenths value = 60 } }
        25 = { set_variable = { name = domcom_pref_length_tenths value = 85 } set_variable = { name = domcom_pref_girth_tenths value = 65 } }
        20 = { set_variable = { name = domcom_pref_length_tenths value = 90 } set_variable = { name = domcom_pref_girth_tenths value = 65 } }
        15 = { set_variable = { name = domcom_pref_length_tenths value = 100 } set_variable = { name = domcom_pref_girth_tenths value = 70 } }
        10 = { set_variable = { name = domcom_pref_length_tenths value = 110 } set_variable = { name = domcom_pref_girth_tenths value = 75 } }
        5  = { set_variable = { name = domcom_pref_length_tenths value = 130 } set_variable = { name = domcom_pref_girth_tenths value = 85 } }
    }
}

# Each Endowment preference has real stored measurements. The initially selected category is only a
# generation bucket; after measurements exist, the visible preference category uses the same length-first
# bands as bodies. Attraction still compares the exact preferred measurements.
domcom_generate_preference_measurements_effect = {
    if = {
        limit = {
            age >= 18
            is_attracted_to_men = yes
            has_variable = domcom_size_preference_primary
            OR = {
                NOT = { has_variable = domcom_pref_length_tenths }
                NOT = { has_variable = domcom_pref_girth_tenths }
            }
        }
        if = { limit = { has_variable = domcom_pref_length_tenths } remove_variable = domcom_pref_length_tenths }
        if = { limit = { has_variable = domcom_pref_girth_tenths } remove_variable = domcom_pref_girth_tenths }

        if = { limit = { var:domcom_size_preference_primary = flag:micro } domcom_seed_preference_micro_effect = yes }
        else_if = { limit = { var:domcom_size_preference_primary = flag:small } domcom_seed_preference_small_effect = yes }
        else_if = { limit = { var:domcom_size_preference_primary = flag:average } domcom_seed_preference_average_effect = yes }
        else_if = { limit = { var:domcom_size_preference_primary = flag:big } domcom_seed_preference_big_effect = yes }
        else_if = { limit = { var:domcom_size_preference_primary = flag:hung } domcom_seed_preference_hung_effect = yes }
        else_if = { limit = { var:domcom_size_preference_primary = flag:massive } domcom_seed_preference_massive_effect = yes }
    }
}

domcom_clear_size_preference_traits_effect = {
    if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
    if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
    if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
    if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
    if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
    if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
}

domcom_sync_size_preference_trait_effect = {
    # Preferred measurements are authoritative. Repair/derive the summary category before touching the
    # visible trait so a label can never disagree with its own stored ideal pair.
    if = {
        limit = {
            age >= 18
            is_attracted_to_men = yes
            has_variable = domcom_pref_length_tenths
            has_variable = domcom_pref_girth_tenths
        }
        # Keep the continuous preferred index for sorting/compatibility only. The label follows the same
        # length-first bands as a body, with girth able to promote by one tier.
        if = { limit = { has_variable = domcom_preferred_endowment_index } remove_variable = domcom_preferred_endowment_index }
        if = {
            limit = { var:domcom_pref_length_tenths <= 25 }
            if = { limit = { var:domcom_pref_girth_tenths <= 35 } set_variable = { name = domcom_size_preference_primary value = flag:micro } }
            else = { set_variable = { name = domcom_size_preference_primary value = flag:small } }
        }
        else_if = {
            limit = { var:domcom_pref_length_tenths < 43 }
            if = { limit = { var:domcom_pref_girth_tenths > 50 } set_variable = { name = domcom_size_preference_primary value = flag:average } }
            else = { set_variable = { name = domcom_size_preference_primary value = flag:small } }
        }
        else_if = {
            limit = { var:domcom_pref_length_tenths < 58 }
            if = { limit = { var:domcom_pref_girth_tenths > 55 } set_variable = { name = domcom_size_preference_primary value = flag:big } }
            else = { set_variable = { name = domcom_size_preference_primary value = flag:average } }
        }
        else_if = {
            limit = { var:domcom_pref_length_tenths < 68 }
            if = { limit = { var:domcom_pref_girth_tenths > 60 } set_variable = { name = domcom_size_preference_primary value = flag:hung } }
            else = { set_variable = { name = domcom_size_preference_primary value = flag:big } }
        }
        else_if = {
            limit = { var:domcom_pref_length_tenths < 83 }
            if = { limit = { var:domcom_pref_girth_tenths > 70 } set_variable = { name = domcom_size_preference_primary value = flag:massive } }
            else = { set_variable = { name = domcom_size_preference_primary value = flag:hung } }
        }
        else = { set_variable = { name = domcom_size_preference_primary value = flag:massive } }
    }

    if = {
        limit = { age >= 18 is_attracted_to_men = yes has_variable = domcom_size_preference_primary }
        if = {
            limit = { var:domcom_size_preference_primary = flag:micro }
            if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
            if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
            if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
            if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
            if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_micro } } add_trait = domcom_prefers_endowment_micro }
        }
        else_if = {
            limit = { var:domcom_size_preference_primary = flag:small }
            if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
            if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
            if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
            if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
            if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_small } } add_trait = domcom_prefers_endowment_small }
        }
        else_if = {
            limit = { var:domcom_size_preference_primary = flag:average }
            if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
            if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
            if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
            if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
            if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_average } } add_trait = domcom_prefers_endowment_average }
        }
        else_if = {
            limit = { var:domcom_size_preference_primary = flag:big }
            if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
            if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
            if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
            if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
            if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_big } } add_trait = domcom_prefers_endowment_big }
        }
        else_if = {
            limit = { var:domcom_size_preference_primary = flag:hung }
            if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
            if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
            if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
            if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
            if = { limit = { has_trait = domcom_prefers_endowment_massive } remove_trait = domcom_prefers_endowment_massive }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_hung } } add_trait = domcom_prefers_endowment_hung }
        }
        else_if = {
            limit = { var:domcom_size_preference_primary = flag:massive }
            if = { limit = { has_trait = domcom_prefers_endowment_micro } remove_trait = domcom_prefers_endowment_micro }
            if = { limit = { has_trait = domcom_prefers_endowment_small } remove_trait = domcom_prefers_endowment_small }
            if = { limit = { has_trait = domcom_prefers_endowment_average } remove_trait = domcom_prefers_endowment_average }
            if = { limit = { has_trait = domcom_prefers_endowment_big } remove_trait = domcom_prefers_endowment_big }
            if = { limit = { has_trait = domcom_prefers_endowment_hung } remove_trait = domcom_prefers_endowment_hung }
            if = { limit = { NOT = { has_trait = domcom_prefers_endowment_massive } } add_trait = domcom_prefers_endowment_massive }
        }
        else = { domcom_clear_size_preference_traits_effect = yes }
    }
    else = { domcom_clear_size_preference_traits_effect = yes }
}

domcom_assign_size_preference_effect = {
    # Old ranked-preference variables are obsolete in 1.2.
    if = { limit = { has_variable = domcom_size_preference } remove_variable = domcom_size_preference }
    if = { limit = { has_variable = domcom_size_preference_secondary } remove_variable = domcom_size_preference_secondary }
    if = { limit = { has_variable = domcom_size_preference_tertiary } remove_variable = domcom_size_preference_tertiary }

    if = {
        limit = { age >= 18 is_attracted_to_men = yes }
        if = {
            limit = { NOT = { has_variable = domcom_size_preference_primary } }
            # Smoothed inverse of the generated Endowment distribution.
            random_list = {
                23 = { set_variable = { name = domcom_size_preference_primary value = flag:micro } }
                12 = { set_variable = { name = domcom_size_preference_primary value = flag:small } }
                12 = { set_variable = { name = domcom_size_preference_primary value = flag:average } }
                13 = { set_variable = { name = domcom_size_preference_primary value = flag:big } }
                17 = { set_variable = { name = domcom_size_preference_primary value = flag:hung } }
                23 = { set_variable = { name = domcom_size_preference_primary value = flag:massive } }
            }
        }
        domcom_generate_preference_measurements_effect = yes
        domcom_sync_size_preference_trait_effect = yes
        # v2.4.3: keep a lazy global index for the Women's Preferences registry view.
        if = {
            limit = {
                is_female = yes
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
                NOT = { is_target_in_global_variable_list = { name = domcom_all_preference_profiles target = this } }
            }
            add_to_global_variable_list = { name = domcom_all_preference_profiles target = this }
        }
    }
    else = {
        domcom_clear_size_preference_traits_effect = yes
    }
}

# Existing saves preserve the old primary category. The new exact preferred measurements are generated
# once inside that category. Adults with no previous preference receive a normal new profile.
domcom_migrate_size_preferences_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_size_preference_measurement_migration_120 } }
        every_living_character = {
            limit = { age >= 18 is_attracted_to_men = yes }
            domcom_assign_size_preference_effect = yes
        }
        set_global_variable = domcom_size_preference_measurement_migration_120
        set_global_variable = domcom_size_preference_migration_120
    }
}

domcom_initialize_ledger_counters_effect = {
    if = { limit = { NOT = { has_variable = domcom_alpha_attempts } } set_variable = { name = domcom_alpha_attempts value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_alpha_successes } } set_variable = { name = domcom_alpha_successes value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_alpha_failures } } set_variable = { name = domcom_alpha_failures value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tantalize_attempts } } set_variable = { name = domcom_tantalize_attempts value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tantalize_successes } } set_variable = { name = domcom_tantalize_successes value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tantalize_failures } } set_variable = { name = domcom_tantalize_failures value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_reverse_alpha_victories } } set_variable = { name = domcom_reverse_alpha_victories value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_public_humiliations } } set_variable = { name = domcom_public_humiliations value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_blood_acknowledged } } set_variable = { name = domcom_blood_acknowledged value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_admirer_nights } } set_variable = { name = domcom_admirer_nights value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_households_owned } } set_variable = { name = domcom_households_owned value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_summons_claimed } } set_variable = { name = domcom_summons_claimed value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_abdications_for_blood } } set_variable = { name = domcom_abdications_for_blood value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_collapses_resolved } } set_variable = { name = domcom_collapses_resolved value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_household_final_resolutions } } set_variable = { name = domcom_household_final_resolutions value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_advance_collected } } set_variable = { name = domcom_tribute_advance_collected value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_advance_shortfall } } set_variable = { name = domcom_tribute_advance_shortfall value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_dynastic_count } } set_variable = { name = domcom_tribute_dynastic_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_gold_count } } set_variable = { name = domcom_tribute_gold_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_household_count } } set_variable = { name = domcom_tribute_household_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_military_count } } set_variable = { name = domcom_tribute_military_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_pending_count } } set_variable = { name = domcom_tribute_pending_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_prestige_count } } set_variable = { name = domcom_tribute_prestige_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_refusal_count } } set_variable = { name = domcom_tribute_refusal_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_alpha_budget_used } } set_variable = { name = domcom_alpha_budget_used value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_household_season_count } } set_variable = { name = domcom_tribute_household_season_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_refusal_season_count } } set_variable = { name = domcom_tribute_refusal_season_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_total_count } } set_variable = { name = domcom_tribute_total_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_tribute_summoned_count } } set_variable = { name = domcom_tribute_summoned_count value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_perfect_gauntlets } } set_variable = { name = domcom_perfect_gauntlets value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_digest_pending } } set_variable = { name = domcom_digest_pending value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_featured_digest_pending } } set_variable = { name = domcom_featured_digest_pending value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_collapse_digest_pending } } set_variable = { name = domcom_collapse_digest_pending value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_last_pulse_featured } } set_variable = { name = domcom_last_pulse_featured value = 0 } }
    if = { limit = { NOT = { has_variable = domcom_last_pulse_collapses } } set_variable = { name = domcom_last_pulse_collapses value = 0 } }
}

domcom_initialize_profile_effect = {
    if = {
        limit = { NOT = { has_variable = domcom_sort_seed } }
        set_variable = { name = domcom_sort_seed value = 0 }
        # hundreds
        random_list = {
            1 = { change_variable = { name = domcom_sort_seed add = 0 } }
            1 = { change_variable = { name = domcom_sort_seed add = 100 } }
            1 = { change_variable = { name = domcom_sort_seed add = 200 } }
            1 = { change_variable = { name = domcom_sort_seed add = 300 } }
            1 = { change_variable = { name = domcom_sort_seed add = 400 } }
            1 = { change_variable = { name = domcom_sort_seed add = 500 } }
            1 = { change_variable = { name = domcom_sort_seed add = 600 } }
            1 = { change_variable = { name = domcom_sort_seed add = 700 } }
            1 = { change_variable = { name = domcom_sort_seed add = 800 } }
            1 = { change_variable = { name = domcom_sort_seed add = 900 } }
        }
        # tens
        random_list = {
            1 = { change_variable = { name = domcom_sort_seed add = 0 } }
            1 = { change_variable = { name = domcom_sort_seed add = 10 } }
            1 = { change_variable = { name = domcom_sort_seed add = 20 } }
            1 = { change_variable = { name = domcom_sort_seed add = 30 } }
            1 = { change_variable = { name = domcom_sort_seed add = 40 } }
            1 = { change_variable = { name = domcom_sort_seed add = 50 } }
            1 = { change_variable = { name = domcom_sort_seed add = 60 } }
            1 = { change_variable = { name = domcom_sort_seed add = 70 } }
            1 = { change_variable = { name = domcom_sort_seed add = 80 } }
            1 = { change_variable = { name = domcom_sort_seed add = 90 } }
        }
        # ones
        random_list = {
            1 = { change_variable = { name = domcom_sort_seed add = 0 } }
            1 = { change_variable = { name = domcom_sort_seed add = 1 } }
            1 = { change_variable = { name = domcom_sort_seed add = 2 } }
            1 = { change_variable = { name = domcom_sort_seed add = 3 } }
            1 = { change_variable = { name = domcom_sort_seed add = 4 } }
            1 = { change_variable = { name = domcom_sort_seed add = 5 } }
            1 = { change_variable = { name = domcom_sort_seed add = 6 } }
            1 = { change_variable = { name = domcom_sort_seed add = 7 } }
            1 = { change_variable = { name = domcom_sort_seed add = 8 } }
            1 = { change_variable = { name = domcom_sort_seed add = 9 } }
        }
    }
    domcom_initialize_ledger_counters_effect = yes
    domcom_assign_endowment_effect = yes
    # v2.4.0: learned Mastery is initialized only after the permanent physical profile exists.
    domcom_initialize_endowment_mastery_effect = yes
    domcom_assign_size_preference_effect = yes
    # 2.5.8: Breast Profiles are independent of Endowment and initialize for adult women / people attracted to women.
    domcom_assign_breast_profile_effect = yes
    domcom_assign_breast_preference_effect = yes
    trigger_event = { on_action = domcom_profile_initialized }
}

# First-generation inheritance from a numbered Slave. The child is not numbered and does not receive
# a Slave nickname merely by inheritance. The inherited status is applied immediately; no custom age gate is used.
domcom_apply_first_generation_slave_obligation_effect = {
    if = {
        limit = {
            exists = scope:domcom_inherited_submission_patron
            NOT = { this = scope:domcom_inherited_submission_patron }
            OR = {
                NOT = { has_variable = domcom_inherited_slave_patron }
                var:domcom_inherited_slave_patron = scope:domcom_inherited_submission_patron
            }
        }
        add_character_flag = domcom_first_generation_slave_obligation
        set_variable = { name = domcom_inherited_slave_patron value = scope:domcom_inherited_submission_patron }
        domcom_activate_first_generation_slave_obligation_effect = yes
    }
}

domcom_activate_first_generation_slave_obligation_effect = {
    if = {
        limit = {
            has_character_flag = domcom_first_generation_slave_obligation
            has_variable = domcom_inherited_slave_patron
            var:domcom_inherited_slave_patron = { is_alive = yes }
        }
        save_scope_as = domcom_inherited_submission_subject
        var:domcom_inherited_slave_patron = { save_scope_as = domcom_inherited_submission_patron }
        add_character_flag = domcom_absolute_devotion
        if = { limit = { NOT = { has_character_modifier = domcom_inherited_submission_modifier } } add_character_modifier = domcom_inherited_submission_modifier }
        add_opinion = { target = scope:domcom_inherited_submission_patron modifier = domcom_final_devotion_opinion }
        scope:domcom_inherited_submission_patron = {
            if = {
                limit = { can_add_hook = { target = scope:domcom_inherited_submission_subject type = loyalty_hook } }
                add_hook_no_toast = { target = scope:domcom_inherited_submission_subject type = loyalty_hook }
            }
        }
    }
}

domcom_apply_dominated_effect = {
    add_character_flag = domcom_dominated
    set_variable = { name = domcom_dominance_patron value = scope:domcom_owner }
    add_character_modifier = domcom_dominated_modifier
    add_opinion = { target = scope:domcom_owner modifier = domcom_dominated_by_opinion }
    domcom_schedule_family_attraction_checks_effect = yes
}

# Refresh the visible 0-1000 Devotion stage. Internal domcom_obedience keys stay unchanged for saves.
domcom_refresh_obedience_stage_effect = {
    # Internal variable names remain unchanged for save compatibility. Reaching 1000 Devotion is itself
    # the terminal threshold: if a Patron is known, the numbered Absolute Submission state is created
    # immediately. The legacy Pet flag remains an internal compatibility marker only.
    if = { limit = { has_variable = domcom_obedience var:domcom_obedience > 1000 } set_variable = { name = domcom_obedience value = 1000 } }
    if = { limit = { has_variable = domcom_obedience var:domcom_obedience < 0 } set_variable = { name = domcom_obedience value = 0 } }

    if = {
        limit = { has_character_flag = domcom_pet }
        domcom_clear_devotion_stage_modifiers_effect = yes
        domcom_clear_obedience_hard_modifiers_effect = yes
        if = { limit = { NOT = { has_character_modifier = domcom_pet_modifier } } add_character_modifier = domcom_pet_modifier }
        domcom_repair_pet_identity_effect = yes
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience >= 1000 }
        if = {
            limit = { has_variable = domcom_obedience_patron }
            var:domcom_obedience_patron = { save_scope_as = domcom_tantalize_patron }
            domcom_create_pet_effect = yes
        }
        else_if = {
            limit = { has_variable = domcom_pet_patron }
            var:domcom_pet_patron = { save_scope_as = domcom_tantalize_patron }
            domcom_create_pet_effect = yes
        }
        else = {
            # A legacy save can reach this branch before its Patron pointer is reconstructed. Keep a visible
            # terminal marker until Ledger/upkeep repair supplies the Patron and reruns this effect.
            if = {
                limit = { NOT = { has_character_modifier = domcom_devotion_ready_modifier } }
                domcom_clear_devotion_stage_modifiers_effect = yes
                add_character_modifier = domcom_devotion_ready_modifier
            }
        }
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience >= 800 }
        if = {
            limit = {
                OR = {
                    NOT = { has_character_modifier = domcom_obedience_devoted_modifier }
                    has_character_modifier = domcom_obedience_interested_modifier
                    has_character_modifier = domcom_obedience_tempted_modifier
                    has_character_modifier = domcom_obedience_attached_modifier
                    has_character_modifier = domcom_obedience_submissive_modifier
                    has_character_modifier = domcom_devotion_ready_modifier
                }
            }
            domcom_clear_devotion_stage_modifiers_effect = yes
            add_character_modifier = domcom_obedience_devoted_modifier
        }
        domcom_obedience_grants_tolerance_trigger_effect = yes
        domcom_apply_obedience_weight_effect = yes
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience >= 600 }
        if = {
            limit = {
                OR = {
                    NOT = { has_character_modifier = domcom_obedience_submissive_modifier }
                    has_character_modifier = domcom_obedience_interested_modifier
                    has_character_modifier = domcom_obedience_tempted_modifier
                    has_character_modifier = domcom_obedience_attached_modifier
                    has_character_modifier = domcom_obedience_devoted_modifier
                    has_character_modifier = domcom_devotion_ready_modifier
                }
            }
            domcom_clear_devotion_stage_modifiers_effect = yes
            add_character_modifier = domcom_obedience_submissive_modifier
        }
        domcom_obedience_grants_tolerance_trigger_effect = yes
        domcom_apply_obedience_weight_effect = yes
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience >= 400 }
        if = {
            limit = {
                OR = {
                    NOT = { has_character_modifier = domcom_obedience_attached_modifier }
                    has_character_modifier = domcom_obedience_interested_modifier
                    has_character_modifier = domcom_obedience_tempted_modifier
                    has_character_modifier = domcom_obedience_submissive_modifier
                    has_character_modifier = domcom_obedience_devoted_modifier
                    has_character_modifier = domcom_devotion_ready_modifier
                }
            }
            domcom_clear_devotion_stage_modifiers_effect = yes
            add_character_modifier = domcom_obedience_attached_modifier
        }
        domcom_obedience_grants_tolerance_trigger_effect = yes
        domcom_apply_obedience_weight_effect = yes
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience >= 200 }
        if = {
            limit = {
                OR = {
                    NOT = { has_character_modifier = domcom_obedience_tempted_modifier }
                    has_character_modifier = domcom_obedience_interested_modifier
                    has_character_modifier = domcom_obedience_attached_modifier
                    has_character_modifier = domcom_obedience_submissive_modifier
                    has_character_modifier = domcom_obedience_devoted_modifier
                    has_character_modifier = domcom_devotion_ready_modifier
                }
            }
            domcom_clear_devotion_stage_modifiers_effect = yes
            add_character_modifier = domcom_obedience_tempted_modifier
        }
        domcom_apply_obedience_weight_effect = yes
    }
    else_if = {
        limit = { has_variable = domcom_obedience var:domcom_obedience > 0 }
        if = {
            limit = {
                OR = {
                    NOT = { has_character_modifier = domcom_obedience_interested_modifier }
                    has_character_modifier = domcom_obedience_tempted_modifier
                    has_character_modifier = domcom_obedience_attached_modifier
                    has_character_modifier = domcom_obedience_submissive_modifier
                    has_character_modifier = domcom_obedience_devoted_modifier
                    has_character_modifier = domcom_devotion_ready_modifier
                }
            }
            domcom_clear_devotion_stage_modifiers_effect = yes
            add_character_modifier = domcom_obedience_interested_modifier
        }
        domcom_apply_obedience_weight_effect = yes
    }
    else = {
        domcom_clear_devotion_stage_modifiers_effect = yes
        domcom_clear_obedience_hard_modifiers_effect = yes
    }

    domcom_external_devotion_stage_sync_effect = yes
}

# Terminal Devotion engine. The legacy domcom_pet flag/name is retained internally for save compatibility;
# player-facing state is Absolute Submission. Numbering is stored on the Patron's dynasty so it survives
# succession and counts across the dynasty rather than one ruler.
domcom_create_pet_effect = {
    save_scope_as = domcom_pet_subject
    scope:domcom_tantalize_patron = {
        domcom_rep_gain_seducer_major_effect = yes
        domcom_rep_gain_patron_major_effect = yes
    }
    add_character_flag = domcom_pet
    add_character_flag = domcom_new_pet_created
    set_variable = { name = domcom_pet_patron value = scope:domcom_tantalize_patron }
    set_variable = { name = domcom_obedience_patron value = scope:domcom_tantalize_patron }
    set_variable = { name = domcom_obedience value = 1000 }
    add_character_modifier = domcom_pet_modifier
    add_opinion = { target = scope:domcom_tantalize_patron modifier = domcom_pet_obedience_opinion }

    if = {
        limit = { exists = scope:domcom_tantalize_patron.dynasty }
        scope:domcom_tantalize_patron.dynasty = {
            if = {
                limit = { NOT = { has_variable = domcom_pet_counter } }
                set_variable = { name = domcom_pet_counter value = 0 }
            }
            change_variable = { name = domcom_pet_counter add = 1 }
            save_scope_as = domcom_pet_dynasty_scope
        }
        set_variable = { name = domcom_pet_dynasty value = scope:domcom_pet_dynasty_scope }
        set_variable = { name = domcom_pet_number value = scope:domcom_pet_dynasty_scope.var:domcom_pet_counter }
        give_nickname = nick_domcom_dynasty_slave
    }
    else = {
        scope:domcom_tantalize_patron = {
            if = {
                limit = { NOT = { has_variable = domcom_personal_pet_counter } }
                set_variable = { name = domcom_personal_pet_counter value = 0 }
            }
            change_variable = { name = domcom_personal_pet_counter add = 1 }
        }
        set_variable = { name = domcom_pet_number value = scope:domcom_tantalize_patron.var:domcom_personal_pet_counter }
        give_nickname = nick_domcom_personal_slave
    }

    domcom_apply_absolute_slave_state_effect = yes

    # A Slave's children inherit one generation of submission to that Slave's Patron. This is not
    # recursive: inherited children do not pass the condition to their own children unless they later
    # become a Slave in their own right. The inherited status has no custom age delay.
    scope:domcom_tantalize_patron = { save_scope_as = domcom_inherited_submission_patron }
    every_child = {
        limit = { is_alive = yes NOT = { this = scope:domcom_inherited_submission_patron } }
        domcom_apply_first_generation_slave_obligation_effect = yes
    }

    scope:domcom_tantalize_patron = {
        add_to_variable_list = { name = domcom_pet_registry target = scope:domcom_pet_subject }
        if = {
            limit = { can_add_hook = { target = scope:domcom_pet_subject type = loyalty_hook } }
            add_hook_no_toast = { target = scope:domcom_pet_subject type = loyalty_hook }
        }
        save_scope_as = domcom_owner
    }

    # Full obedience finally grants the same kind of household access that an Outclassed rival can
    # expose, but Pet itself remains distinct from Cucked/Owned.
    domcom_schedule_family_attraction_checks_effect = yes
    domcom_refresh_obedience_stage_effect = yes
    trigger_event = { on_action = domcom_pet_created }
}

# Run from the Tantalize recipient with scope:domcom_tantalize_patron saved. A base success now scales
# with compatibility; established intimate bonds accelerate the track, and a prior same-sex Alpha victory
# against this target adds extra leverage.
domcom_apply_tantalize_success_effect = {
    if = {
        limit = { NOT = { has_variable = domcom_obedience_patron } }
        set_variable = { name = domcom_obedience_patron value = scope:domcom_tantalize_patron }
    }
    if = { limit = { NOT = { has_variable = domcom_obedience } } set_variable = { name = domcom_obedience value = 0 } }

    if = {
        limit = { NOT = { has_character_flag = domcom_tantalized_registered } }
        add_character_flag = domcom_tantalized_registered
        save_temporary_scope_as = domcom_tantalize_subject
        scope:domcom_tantalize_patron = {
            add_to_variable_list = { name = domcom_tantalized_registry target = scope:domcom_tantalize_subject }
        }
    }

    change_variable = { name = domcom_obedience add = domcom_tantalize_obedience_gain_value }
    if = { limit = { has_relation_lover = scope:domcom_tantalize_patron } change_variable = { name = domcom_obedience add = 50 } }
    if = { limit = { has_relation_soulmate = scope:domcom_tantalize_patron } change_variable = { name = domcom_obedience add = 100 } }
    if = {
        limit = {
            has_character_flag = domcom_dominated
            has_variable = domcom_dominance_patron
            var:domcom_dominance_patron = scope:domcom_tantalize_patron
        }
        change_variable = { name = domcom_obedience add = 25 }
    }

    # A first successful Tantalize creates interest, not an affair. Vanilla Seduce/Romance or later
    # Dominion mechanics can still determine intimacy.
    if = {
        limit = {
            NOR = {
                has_relation_crush = scope:domcom_tantalize_patron
                has_relation_lover = scope:domcom_tantalize_patron
                has_relation_soulmate = scope:domcom_tantalize_patron
            }
        }
        set_relation_crush = scope:domcom_tantalize_patron
    }

    if = { limit = { var:domcom_obedience > 1000 } set_variable = { name = domcom_obedience value = 1000 } }
    domcom_refresh_obedience_stage_effect = yes

    # 2.5.1: when an AI successfully works on a human player's lawful partner, tell the player and queue
    # the later confrontation before Dominion can consummate the relationship.
    if = {
        limit = {
            scope:domcom_tantalize_patron = { is_ai = yes }
            any_consort = { is_alive = yes age >= 18 is_ai = no }
        }
        domcom_queue_ai_courtship_against_player_effect = yes
    }

}

# If a lower-status challenger reverses the expected hierarchy, the victory itself becomes a source of
# standing.
domcom_apply_reverse_alpha_reward_effect = {
    # Any victory upward in the hierarchy creates relationship-scheme momentum.
    add_prestige = 300
    add_character_modifier = { modifier = domcom_reverse_alpha_victory_modifier years = 10 }

    # Major upset: roughly two or more social tiers above the challenger.
    if = {
        limit = {
            OR = {
                AND = { scope:recipient = { highest_held_title_tier = tier_duchy } is_landed = no }
                AND = { scope:recipient = { highest_held_title_tier = tier_kingdom } OR = { is_landed = no highest_held_title_tier = tier_county } }
                AND = { scope:recipient = { highest_held_title_tier >= tier_empire } OR = { is_landed = no highest_held_title_tier = tier_county highest_held_title_tier = tier_duchy } }
            }
        }
        add_prestige = 300
        add_character_modifier = { modifier = domcom_reverse_alpha_major_upset_modifier years = 10 }
    }

    # Legendary upset: a landless challenger topples a King/Emperor, or a Count overcomes an Emperor.
    # This stacks with the base and Major Upset rewards.
    if = {
        limit = {
            OR = {
                AND = { scope:recipient = { highest_held_title_tier = tier_kingdom } is_landed = no }
                AND = { scope:recipient = { highest_held_title_tier >= tier_empire } OR = { is_landed = no highest_held_title_tier = tier_county } }
            }
        }
        add_prestige = 400
        add_character_modifier = { modifier = domcom_reverse_alpha_legendary_upset_modifier years = 10 }
    }

    change_variable = { name = domcom_reverse_alpha_victories add = 1 }
}


domcom_refresh_spawn_of_cuck_effect = {
    if = {
        limit = {
            has_character_modifier = domcom_spawn_of_cuck_modifier
            NOT = { domcom_is_spawn_of_cuck_trigger = yes }
        }
        remove_character_modifier = domcom_spawn_of_cuck_modifier
    }
    if = {
        limit = {
            exists = mother mother = { has_character_flag = domcom_cucked }
            NOT = { has_character_modifier = domcom_spawn_of_cuck_modifier }
        }
        add_character_modifier = domcom_spawn_of_cuck_modifier
    }
    else_if = {
        limit = {
            exists = real_father real_father = { has_character_flag = domcom_cucked }
            NOT = { has_character_modifier = domcom_spawn_of_cuck_modifier }
        }
        add_character_modifier = domcom_spawn_of_cuck_modifier
    }
    else_if = {
        limit = {
            NOT = { exists = real_father }
            exists = father
            father = { has_character_flag = domcom_cucked }
            NOT = { has_character_modifier = domcom_spawn_of_cuck_modifier }
        }
        add_character_modifier = domcom_spawn_of_cuck_modifier
    }
}

domcom_register_global_cuck_stigma_effect = {
    # The flag is only a cache marker. The global list is authoritative for the World Cucks/Cucked
    # ledgers, so always verify list membership even when an older save already has the marker.
    if = {
        limit = { has_character_flag = domcom_cucked }
        if = { limit = { NOT = { has_character_flag = domcom_global_cuck_registry_added } } add_character_flag = domcom_global_cuck_registry_added }
        if = { limit = { NOT = { has_trait = domcom_cucked_trait } } add_trait = domcom_cucked_trait }
        if = {
            limit = { NOT = { is_target_in_global_variable_list = { name = domcom_all_cucked target = this } } }
            add_to_global_variable_list = { name = domcom_all_cucked target = this }
        }
    }
}

# Run from a Cucked character. Reassert all visible/public consequences from authoritative state. This is
# safe on registration, Ledger repair, and upkeep: the nickname helper first checks whether the character
# already has it.
domcom_refresh_cuck_reputation_effect = {
    if = {
        limit = { has_character_flag = domcom_cucked }
        remove_character_modifier = domcom_cucked_modifier
        if = {
            limit = { OR = { has_character_flag = domcom_feminized has_trait = domcom_feminized_trait } }
            domcom_refresh_feminized_reputation_effect = yes
        }
        else = { domcom_award_cucked_nickname_effect = yes }
        if = {
            limit = { has_character_flag = domcom_pet }
            domcom_refresh_obedience_stage_effect = yes
        }
        domcom_register_global_cuck_stigma_effect = yes
        every_child = {
            limit = { is_alive = yes }
            domcom_refresh_spawn_of_cuck_effect = yes
        }
    }
}

# Fast upkeep from the patron-local registry. This prevents vanilla/random nickname systems from
# permanently replacing the Dominion reputation without performing any world scan.
domcom_reassert_cuck_reputations_for_patron_effect = {
    save_scope_as = domcom_reputation_patron
    if = {
        limit = { has_variable_list = domcom_cucked_registry }
        every_in_list = {
            variable = domcom_cucked_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_cucked
                OR = {
                    AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_reputation_patron }
                    AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_reputation_patron }
                }
            }
            domcom_refresh_cuck_reputation_effect = yes
        }
    }
}
domcom_refresh_cuck_stage_effect = {
    # Cuck XP is a bounded 0–1000 progression.
    if = {
        limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp > 1000 }
        set_variable = { name = domcom_cuck_xp value = 1000 }
    }
    if = {
        limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp < 0 }
        set_variable = { name = domcom_cuck_xp value = 0 }
    }

    # Transition-only stage maintenance avoids losing and immediately regaining the same modifier every
    # monthly repair pulse.
    if = {
        limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp >= 750 }
        if = { limit = { has_character_modifier = domcom_humiliated_stage_modifier } remove_character_modifier = domcom_humiliated_stage_modifier }
        if = { limit = { has_character_modifier = domcom_submissive_stage_modifier } remove_character_modifier = domcom_submissive_stage_modifier }
        if = { limit = { has_character_modifier = domcom_broken_stage_modifier } remove_character_modifier = domcom_broken_stage_modifier }
        if = { limit = { NOT = { has_character_modifier = domcom_abject_stage_modifier } } add_character_modifier = domcom_abject_stage_modifier }
    }
    else_if = {
        limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp >= 500 }
        if = { limit = { has_character_modifier = domcom_humiliated_stage_modifier } remove_character_modifier = domcom_humiliated_stage_modifier }
        if = { limit = { has_character_modifier = domcom_submissive_stage_modifier } remove_character_modifier = domcom_submissive_stage_modifier }
        if = { limit = { has_character_modifier = domcom_abject_stage_modifier } remove_character_modifier = domcom_abject_stage_modifier }
        if = { limit = { NOT = { has_character_modifier = domcom_broken_stage_modifier } } add_character_modifier = domcom_broken_stage_modifier }
    }
    else_if = {
        limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp >= 250 }
        if = { limit = { has_character_modifier = domcom_humiliated_stage_modifier } remove_character_modifier = domcom_humiliated_stage_modifier }
        if = { limit = { has_character_modifier = domcom_broken_stage_modifier } remove_character_modifier = domcom_broken_stage_modifier }
        if = { limit = { has_character_modifier = domcom_abject_stage_modifier } remove_character_modifier = domcom_abject_stage_modifier }
        if = { limit = { NOT = { has_character_modifier = domcom_submissive_stage_modifier } } add_character_modifier = domcom_submissive_stage_modifier }
    }
    else = {
        if = { limit = { has_character_modifier = domcom_submissive_stage_modifier } remove_character_modifier = domcom_submissive_stage_modifier }
        if = { limit = { has_character_modifier = domcom_broken_stage_modifier } remove_character_modifier = domcom_broken_stage_modifier }
        if = { limit = { has_character_modifier = domcom_abject_stage_modifier } remove_character_modifier = domcom_abject_stage_modifier }
        if = { limit = { NOT = { has_character_modifier = domcom_humiliated_stage_modifier } } add_character_modifier = domcom_humiliated_stage_modifier }
    }

    domcom_external_cuck_stage_sync_effect = yes
}

# Generic registration. Run from the prospective cuck with scope:domcom_owner saved.
domcom_register_cuck_generic_effect = {
    if = {
        limit = { NOT = { has_character_flag = domcom_reclaimed_cuck_recent } }

    save_scope_as = domcom_cuck_subject

    if = {
        limit = {
            exists = scope:domcom_owner
            NOT = { this = scope:domcom_owner }
            NOT = { is_consort_of = scope:domcom_owner }
        }

        if = {
            limit = { NOT = { has_variable = domcom_cuck_origin_patron } }
            set_variable = { name = domcom_cuck_origin_patron value = scope:domcom_owner }
        }
        if = {
            limit = {
                NOT = {
                    any_in_list = {
                        variable = domcom_cuck_patrons
                        this = scope:domcom_owner
                    }
                }
            }
            add_to_variable_list = { name = domcom_cuck_patrons target = scope:domcom_owner }
        }

        set_variable = { name = domcom_cuck_patron value = scope:domcom_owner }

        if = {
            limit = {
                OR = {
                    NOT = { has_variable = domcom_cuck_registry_patron }
                    NOT = { var:domcom_cuck_registry_patron = scope:domcom_owner }
                }
            }
            if = {
                limit = { has_variable = domcom_cuck_registry_patron }
                var:domcom_cuck_registry_patron = {
                    if = {
                        limit = { has_variable_list = domcom_cucked_registry }
                        remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_cuck_subject }
                    }
                }
            }
            set_variable = { name = domcom_cuck_registry_patron value = scope:domcom_owner }
        }

        # Registry membership can be lost independently of the cached patron/added flags in old saves.
        # Reassert it every time a valid cuck record is registered, without duplicating the list entry.
        scope:domcom_owner = {
            if = {
                limit = {
                    OR = {
                        NOT = { has_variable_list = domcom_cucked_registry }
                        NOT = { any_in_list = { variable = domcom_cucked_registry this = scope:domcom_cuck_subject } }
                    }
                }
                add_to_variable_list = { name = domcom_cucked_registry target = scope:domcom_cuck_subject }
            }
        }
        if = { limit = { NOT = { has_character_flag = domcom_cuck_registry_added } } add_character_flag = domcom_cuck_registry_added }

        if = {
            limit = { NOT = { has_character_flag = domcom_cucked } }
            add_character_flag = domcom_cucked
            if = { limit = { NOT = { has_trait = domcom_cucked_trait } } add_trait = domcom_cucked_trait }
            set_variable = { name = domcom_cuck_xp value = 100 }
            every_spouse = {
                limit = {
                    is_alive = yes
                    age >= 18
                    OR = {
                        has_relation_lover = scope:domcom_owner
                        has_relation_soulmate = scope:domcom_owner
                        any_child = {
                            OR = {
                                father ?= scope:domcom_owner
                                mother ?= scope:domcom_owner
                                real_father ?= scope:domcom_owner
                            }
                        }
                    }
                }
                save_temporary_scope_as = domcom_compromised_partner
                scope:domcom_cuck_subject = {
                    if = {
                        limit = { NOT = { has_variable = domcom_compromised_partner } }
                        set_variable = { name = domcom_compromised_partner value = scope:domcom_compromised_partner }
                    }
                    if = {
                        limit = {
                            NOT = {
                                any_in_list = {
                                    variable = domcom_compromised_partners
                                    this = scope:domcom_compromised_partner
                                }
                            }
                        }
                        add_to_variable_list = { name = domcom_compromised_partners target = scope:domcom_compromised_partner }
                    }
                    add_opinion = { target = scope:domcom_compromised_partner modifier = domcom_cucked_partner_opinion }
                }
                if = {
                    limit = { has_relation_soulmate = scope:domcom_owner }
                    scope:domcom_cuck_subject = { change_variable = { name = domcom_cuck_xp add = 150 } }
                }
                else_if = {
                    limit = { has_relation_lover = scope:domcom_owner }
                    scope:domcom_cuck_subject = { change_variable = { name = domcom_cuck_xp add = 75 } }
                }
                every_child = {
                    limit = {
                        OR = {
                            father ?= scope:domcom_owner
                            mother ?= scope:domcom_owner
                            real_father ?= scope:domcom_owner
                        }
                    }
                    save_temporary_scope_as = domcom_evidence_child
                    scope:domcom_cuck_subject = {
                        change_variable = { name = domcom_cuck_xp add = 125 }
                        add_opinion = { target = scope:domcom_evidence_child modifier = domcom_cucked_child_opinion }
                    }
                }
            }
            domcom_refresh_cuck_stage_effect = yes
        }

        # Always reassert the public reputation, including older saves or a later vanilla nickname
        # replacement. Any character carrying domcom_cucked gets it.
        domcom_refresh_cuck_reputation_effect = yes
    }
    }
}

domcom_register_cuck_effect = {
    scope:actor = { save_scope_as = domcom_owner }
    domcom_register_cuck_generic_effect = yes
}

# Register a successful post-Alpha attraction check. Run from candidate with
# scope:domcom_attraction_patron saved.
domcom_register_communion_admirer_effect = {
    save_scope_as = domcom_admirer_candidate
    if = {
        limit = {
            is_alive = yes
            age >= 18
            NOT = { this = scope:domcom_attraction_patron }
            NOT = { is_close_or_extended_family_of = scope:domcom_attraction_patron }
            scope:domcom_attraction_patron = { is_attracted_to_gender_of = prev }
            is_attracted_to_gender_of = scope:domcom_attraction_patron
        }
        if = {
            limit = {
                NOR = {
                    has_relation_crush = scope:domcom_attraction_patron
                    has_relation_lover = scope:domcom_attraction_patron
                    has_relation_soulmate = scope:domcom_attraction_patron
                }
            }
            set_relation_crush = scope:domcom_attraction_patron
        }
        set_variable = { name = domcom_crush_patron value = scope:domcom_attraction_patron }

        # Preserve the exact controlled relative whose post-Alpha check produced this admirer. Later
        # family humiliation must match this source; merely being related to some other Owned character
        # is not enough.
        if = {
            limit = { exists = scope:domcom_attraction_source }
            set_variable = { name = domcom_crush_source value = scope:domcom_attraction_source }
            scope:domcom_attraction_source = {
                add_to_variable_list = {
                    name = domcom_family_admirers
                    target = scope:domcom_admirer_candidate
                }
            }
        }

        add_character_flag = domcom_communion_admirer_registered
        remove_character_flag = domcom_communion_attraction_pending
        scope:domcom_attraction_patron = {
            add_to_variable_list = { name = domcom_crush_candidates target = scope:domcom_admirer_candidate }
            domcom_digest_note_admirer_effect = yes
        }
        if = {
            # Everything restores the old immediate approach event for every successful prospect. This is
            # intentionally noisy and exists only for players who explicitly opt into the firehose.
            limit = {
                has_game_rule = domcom_notifications_everything
                scope:domcom_attraction_patron = { is_ai = no }
            }
            save_scope_as = domcom_admirer
            scope:domcom_attraction_patron = { trigger_event = { id = domcom.200 days = 1 } }
        }
        else_if = {
            # Strategic (and the fallback for older saves without the new rule recorded) batches only
            # high-quality/genetically valuable or King+ prospects into the quarterly Dominion Pulse.
            limit = {
                domcom_is_strategic_prospect_trigger = yes
                NOT = { has_game_rule = domcom_notifications_minimal }
                NOT = { has_game_rule = domcom_notifications_everything }
            }
            add_character_flag = domcom_featured_prospect
            scope:domcom_attraction_patron = {
                if = { limit = { NOT = { has_variable = domcom_featured_digest_pending } } set_variable = { name = domcom_featured_digest_pending value = 0 } }
                change_variable = { name = domcom_featured_digest_pending add = 1 }
            }
        }
    }
}

# Run from an Owned subject with scope:domcom_owner saved. Family members do not automatically fall for
# the patron; each eligible adult gets a delayed check.
domcom_schedule_family_attraction_checks_effect = {
    save_scope_as = domcom_attraction_source
    every_close_or_extended_family_member = {
        limit = {
            is_alive = yes
            age >= 18
            NOT = { this = scope:domcom_owner }
            NOT = { is_close_or_extended_family_of = scope:domcom_owner }
            NOT = { is_consort_of = scope:domcom_owner }
            NOT = { has_relation_lover = scope:domcom_owner }
            NOT = { has_relation_soulmate = scope:domcom_owner }
            NOT = { has_relation_crush = scope:domcom_owner }
            NOT = { has_character_flag = domcom_communion_admirer_registered }
            NOT = { has_character_flag = domcom_communion_attraction_pending }
            scope:domcom_owner = { is_attracted_to_gender_of = prev }
            is_attracted_to_gender_of = scope:domcom_owner
        }
        domcom_initialize_attraction_profile_effect = yes
        add_character_flag = domcom_communion_attraction_pending
        save_scope_as = domcom_attraction_candidate
        scope:domcom_owner = { save_scope_as = domcom_attraction_patron domcom_initialize_profile_effect = yes }
        trigger_event = { id = domcom.210 days = { 2 5 } }
    }
}

domcom_reveal_subject_network_effect = {
    # Run from an Owned subject with scope:domcom_secret_patron saved.
    every_secret = { reveal_to = scope:domcom_secret_patron }
    every_vassal_or_below = { every_secret = { reveal_to = scope:domcom_secret_patron } }
    if = {
        limit = { highest_held_title_tier >= tier_kingdom }
        every_courtier = { every_secret = { reveal_to = scope:domcom_secret_patron } }
    }
}

# Detect the special case where both spouses are Owned by the same patron.
domcom_refresh_household_dominion_effect = {
    if = {
        limit = { has_character_flag = domcom_owned_cuck has_variable = domcom_patron is_married = yes }
        save_scope_as = domcom_household_subject
        var:domcom_patron = { save_scope_as = domcom_household_patron }
        every_spouse = {
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_household_patron
            }
            save_scope_as = domcom_household_spouse
            if = {
                limit = {
                    OR = {
                        scope:domcom_household_subject = { NOT = { has_character_flag = domcom_household_dominion } }
                        NOT = { has_character_flag = domcom_household_dominion }
                    }
                }
                add_character_flag = domcom_household_dominion
                add_character_modifier = domcom_household_dominion_modifier
                change_variable = { name = domcom_cuck_xp add = 100 }
                domcom_refresh_cuck_stage_effect = yes
                scope:domcom_household_subject = {
                    add_character_flag = domcom_household_dominion
                    add_character_modifier = domcom_household_dominion_modifier
                    change_variable = { name = domcom_cuck_xp add = 100 }
                    domcom_refresh_cuck_stage_effect = yes
                }
                scope:domcom_household_patron = {
                    change_variable = { name = domcom_households_owned add = 1 }
                    if = {
                        limit = { is_ai = no }
                        send_interface_toast = {
                            type = event_toast_effect_good
                            title = domcom_household_dominion_toast
                            left_icon = scope:domcom_household_subject
                            right_icon = scope:domcom_household_spouse
                        }
                    }
                }
            }
        }
    }
}

# Generic ownership result. Run from the cuck with scope:domcom_owner saved.
domcom_own_cuck_generic_effect = {
    # Ownership can never point back to the subject, including succession/mod-compatibility edge cases.
    if = {
        limit = { exists = scope:domcom_owner NOT = { this = scope:domcom_owner } }

        save_scope_as = domcom_owned_subject
        scope:domcom_owner = { domcom_rep_gain_breaker_major_effect = yes }
        add_character_flag = domcom_owned_cuck
        set_variable = { name = domcom_patron value = scope:domcom_owner }
        set_variable = { name = domcom_cuck_patron value = scope:domcom_owner }
        if = {
            limit = { exists = scope:domcom_owner.dynasty }
            set_variable = { name = domcom_patron_dynasty value = scope:domcom_owner.dynasty }
        }
        add_character_modifier = domcom_owned_modifier
        add_opinion = { target = scope:domcom_owner modifier = domcom_owned_by_patron_opinion }

        scope:domcom_owner = {
            if = {
                limit = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_owned_registry
                            this = scope:domcom_owned_subject
                        }
                    }
                }
                add_to_variable_list = { name = domcom_owned_registry target = scope:domcom_owned_subject }
            }
        }

        scope:domcom_owner = {
            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 }
            }
        }

        # Update the human Patron's passive Dominion tier immediately rather than waiting for the next
        # monthly maintenance pulse.
        scope:domcom_owner = {
            if = { limit = { is_ai = no } domcom_refresh_owned_benefit_tier_effect = yes }
        }

        if = {
            limit = { exists = scope:domcom_owner.dynasty }
            scope:domcom_owner.dynasty = {
                add_to_variable_list = { name = domcom_owned_subjects target = scope:domcom_owned_subject }
                every_dynasty_member = {
                    limit = { is_alive = yes }
                    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 }
                    }
                }
            }
        }

        scope:domcom_owner = { save_scope_as = domcom_secret_patron }
        domcom_reveal_subject_network_effect = yes

        if = {
            limit = { highest_held_title_tier >= tier_kingdom }
            add_character_modifier = domcom_royal_dominion_modifier
        }

        scope:domcom_owner = { save_scope_as = domcom_communion_patron }
        domcom_apply_communion_tolerance_subject_effect = yes
        domcom_refresh_cuck_stage_effect = yes
        domcom_schedule_family_attraction_checks_effect = yes
        domcom_refresh_household_dominion_effect = yes

        # A Cucked victor can reclaim standing by successfully establishing Dominion over somebody else.
        # v2.5.0: winning an Alpha/Dominion contest no longer silently erases the winner's own cuck record.
        # Personal cuck status changes only through evidence/repair or the explicit player opt-out decision.
    }
}

domcom_own_cuck_effect = {
    scope:actor = { save_scope_as = domcom_owner }
    domcom_own_cuck_generic_effect = yes
}

domcom_add_public_humiliation_xp_effect = {
    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 0 } }
    change_variable = { name = domcom_cuck_xp add = 200 }
    if = { limit = { highest_held_title_tier = tier_duchy } change_variable = { name = domcom_cuck_xp add = 50 } }
    else_if = { limit = { highest_held_title_tier = tier_kingdom } change_variable = { name = domcom_cuck_xp add = 125 } }
    else_if = { limit = { highest_held_title_tier >= tier_empire } change_variable = { name = domcom_cuck_xp add = 200 } }
    if = { limit = { has_character_flag = domcom_household_dominion } change_variable = { name = domcom_cuck_xp add = 75 } }
    domcom_refresh_cuck_stage_effect = yes
}

# Generic public humiliation. Run from selected partner with scope:domcom_public_patron and
# scope:domcom_humiliated_cuck saved.
# Shared preparation for GUI/right-click embarrassment attempts. Run from the Owned target after
# scope:domcom_public_patron has been saved. The four-month flag means at most three attempts per year.
domcom_prepare_embarrass_attempt_effect = {
    if = {
        limit = {
            OR = {
                NOT = { has_variable = domcom_embarrass_counter_patron }
                NOT = { var:domcom_embarrass_counter_patron = scope:domcom_public_patron }
            }
        }
        set_variable = { name = domcom_embarrass_counter_patron value = scope:domcom_public_patron }
        set_variable = { name = domcom_embarrass_successes value = 0 }
    }
    add_character_flag = { flag = domcom_embarrass_attempt_cooldown months = 4 }
}

# Run from the Patron with domcom_public_partner and domcom_humiliated_cuck saved. A failed attempt
# consumes the four-month attempt slot but grants no Cuck XP, Prestige or humiliation count.
domcom_resolve_embarrass_attempt_effect = {
    add_character_flag = { flag = domcom_embarrass_failed_roll days = 1 }
    random = {
        chance = domcom_embarrass_success_chance_value
        remove_character_flag = domcom_embarrass_failed_roll
        scope:domcom_public_partner = { domcom_apply_public_humiliation_generic_effect = yes }
        scope:domcom_humiliated_cuck = {
            if = { limit = { NOT = { has_variable = domcom_embarrass_successes } } set_variable = { name = domcom_embarrass_successes value = 0 } }
            change_variable = { name = domcom_embarrass_successes add = 1 }
        }
        change_variable = { name = domcom_public_humiliations add = 1 }
        if = {
            limit = { is_ai = no }
            send_interface_toast = {
                type = event_toast_effect_good
                title = domcom_public_humiliation_toast
                left_icon = root
                right_icon = scope:domcom_humiliated_cuck
            }
        }
    }
    if = {
        limit = { has_character_flag = domcom_embarrass_failed_roll }
        remove_character_flag = domcom_embarrass_failed_roll
        if = {
            limit = { is_ai = no }
            send_interface_toast = {
                type = event_toast_effect_neutral
                title = domcom_public_humiliation_failed_toast
                left_icon = root
                right_icon = scope:domcom_humiliated_cuck
            }
        }
    }
}

domcom_apply_public_humiliation_generic_effect = {
    save_scope_as = domcom_public_partner
    if = {
        limit = {
            NOT = { has_relation_lover = scope:domcom_public_patron }
            scope:domcom_public_patron = {
                NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_public_partner } }
            }
        }
        set_relation_lover = scope:domcom_public_patron
    }
    scope:domcom_public_patron = { save_scope_as = domcom_communion_patron }
    if = {
        limit = {
            scope:domcom_public_patron = {
                NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_public_partner } }
            }
        }
        domcom_register_communion_intimate_effect = yes
    }

    if = {
        limit = {
            is_female = yes
            is_visibly_fertile = yes
            is_pregnant = no
            scope:domcom_public_patron = { is_male = yes is_visibly_fertile = yes }
        }
        make_pregnant = { father = scope:domcom_public_patron number_of_children = 1 known_bastard = no }
    }
    else_if = {
        limit = {
            is_male = yes
            is_visibly_fertile = yes
            scope:domcom_public_patron = { is_female = yes is_visibly_fertile = yes is_pregnant = no }
        }
        scope:domcom_public_patron = {
            make_pregnant = { father = scope:domcom_public_partner number_of_children = 1 known_bastard = no }
        }
    }

    scope:domcom_humiliated_cuck = {
        domcom_add_public_humiliation_xp_effect = yes
        every_courtier = {
            add_opinion = { target = scope:domcom_humiliated_cuck modifier = domcom_public_humiliation_target_opinion }
            add_opinion = { target = scope:domcom_public_patron modifier = domcom_public_humiliation_patron_opinion }
        }
        if = {
            limit = { highest_held_title_tier >= tier_empire }
            scope:domcom_public_patron = { add_prestige = 500 add_dread = 15 }
        }
        else_if = {
            limit = { highest_held_title_tier = tier_kingdom }
            scope:domcom_public_patron = { add_prestige = 250 add_dread = 10 }
        }
        else_if = {
            limit = { highest_held_title_tier = tier_duchy }
            scope:domcom_public_patron = { add_prestige = 125 add_dread = 5 }
        }
        else = { scope:domcom_public_patron = { add_prestige = 50 } }
        domcom_check_final_collapse_effect = yes
    }
}

domcom_apply_public_humiliation_effect = {
    scope:actor = { save_scope_as = domcom_public_patron }
    domcom_apply_public_humiliation_generic_effect = yes
}

# Japanese/Admin/Celestial Noble Family terminal conquest. A Noble Family title belongs to its
# House and cannot legally become the Patron's family title. If the Patron's government can host
# Noble Families, Final Collapse instead turns the defeated House into a client political family:
# the Toshu remains holder of the family identity/manor while eligible landed members from the same
# political realm are compelled beneath the Patron. This is the non-war map-painting analogue of
# subjugation. Governments that cannot host Noble Families fall back to direct confiscation.
domcom_resolve_noble_family_conquest_effect = {
    save_scope_as = domcom_family_subject
    domcom_record_terminal_outcome_effect = { OUTCOME = flag:noble_family }
    domcom_surrender_prestige_if_lower_effect = yes
    if = { limit = { gold > 0 } pay_short_term_gold = { target = scope:domcom_collapse_patron gold = gold } }

    house = { save_scope_as = domcom_collapsed_house }
    top_liege = { save_scope_as = domcom_family_old_top_liege }
    every_held_title = {
        limit = { is_noble_family_title = yes }
        save_scope_as = domcom_collapsed_family_title
    }

    if = {
        limit = {
            scope:domcom_collapse_patron = {
                OR = {
                    government_allows = noble_families
                    government_allows = administrative
                }
            }
        }

        # Keep the Noble Family and Manor intact but permanently record whose Dominion it entered.
        if = {
            limit = { exists = scope:domcom_collapsed_family_title }
            scope:domcom_collapsed_family_title = {
                set_variable = { name = domcom_client_family_patron value = scope:domcom_collapse_patron }
            }
        }

        # The family head can itself be a landless vassal. Vanilla administrative governments support
        # this; change_liege is the same class of title/vassal change used by vanilla setup.
        if = {
            limit = {
                NOT = { this = scope:domcom_collapse_patron }
                NOT = { is_vassal_of = scope:domcom_collapse_patron }
                highest_held_title_tier < scope:domcom_collapse_patron.highest_held_title_tier
            }
            if = { limit = { is_landed = no } set_employer = scope:domcom_collapse_patron }
            create_title_and_vassal_change = { type = swear_fealty save_scope_as = domcom_family_head_change }
            change_liege = { liege = scope:domcom_collapse_patron change = scope:domcom_family_head_change }
            resolve_title_and_vassal_change = scope:domcom_family_head_change
        }

        # Bring the ordinary landed branch of this House from the defeated political realm with it.
        # We deliberately scope this to the old top realm: collapsing one cousin must not steal every
        # distant cadet holding of the House across the entire world.
        if = {
            limit = { exists = scope:domcom_collapsed_house exists = scope:domcom_family_old_top_liege }
            scope:domcom_collapsed_house = {
                every_house_member = {
                    limit = {
                        is_alive = yes
                        is_landed = yes
                        NOT = { this = scope:domcom_collapse_patron }
                        top_liege = scope:domcom_family_old_top_liege
                        NOT = { is_vassal_of = scope:domcom_collapse_patron }
                        highest_held_title_tier < scope:domcom_collapse_patron.highest_held_title_tier
                    }
                    create_title_and_vassal_change = { type = swear_fealty save_scope_as = domcom_family_member_change }
                    change_liege = { liege = scope:domcom_collapse_patron change = scope:domcom_family_member_change }
                    resolve_title_and_vassal_change = scope:domcom_family_member_change
                }
            }
        }

        add_character_flag = domcom_bound_ruler
        if = { limit = { NOT = { has_character_modifier = domcom_bound_ruler_modifier } } add_character_modifier = domcom_bound_ruler_modifier }
        add_opinion = { target = scope:domcom_collapse_patron modifier = domcom_bound_ruler_opinion }
    }
    else = {
        # A government that cannot legally contain a landless Noble Family cannot preserve the Manor
        # as a vassal institution. Confiscate ordinary House land from the same old realm, then
        # extinguish the family title rather than attempting an illegal grant.
        if = {
            limit = { exists = scope:domcom_collapsed_house exists = scope:domcom_family_old_top_liege }
            scope:domcom_collapsed_house = {
                every_house_member = {
                    limit = {
                        is_alive = yes
                        NOT = { this = scope:domcom_collapse_patron }
                        top_liege = scope:domcom_family_old_top_liege
                        any_held_title = { domcom_collapse_transferable_title_trigger = yes }
                    }
                    create_title_and_vassal_change = { type = granted save_scope_as = domcom_family_seizure_change add_claim_on_loss = yes }
                    every_held_title = {
                        limit = { domcom_collapse_transferable_title_trigger = yes }
                        if = {
                            limit = { scope:domcom_collapse_patron = { is_ai = no } }
                            set_variable = { name = domcom_final_collapse_journal_patron value = scope:domcom_collapse_patron }
                        }
                        change_title_holder = {
                            holder = scope:domcom_collapse_patron
                            change = scope:domcom_family_seizure_change
                            government_base = scope:domcom_collapse_patron
                        }
                    }
                    resolve_title_and_vassal_change = scope:domcom_family_seizure_change
                }
            }
        }
        every_held_title = {
            limit = { is_noble_family_title = yes }
            add_to_temporary_list = domcom_family_titles_to_extinguish
        }
        every_in_list = {
            list = domcom_family_titles_to_extinguish
            save_temporary_scope_as = domcom_family_title_to_extinguish
            scope:domcom_family_subject = { destroy_title = scope:domcom_family_title_to_extinguish }
        }
    }

    remove_character_flag = domcom_collapse_ready
    remove_character_flag = domcom_collapse_pending
    remove_character_flag = domcom_collapse_seizure_failed
    add_character_flag = domcom_collapse_resolved
    if = { limit = { NOT = { has_character_modifier = domcom_final_submission_modifier } } add_character_modifier = domcom_final_submission_modifier }
    scope:domcom_collapse_patron = {
        change_variable = { name = domcom_collapses_resolved add = 1 }
        if = {
            limit = { is_ai = no }
            create_character_memory = {
                type = domcom_final_collapse_realm_transfer_memory
                participants = { submitted_ruler = scope:domcom_family_subject }
            }
            trigger_event = { id = domcom.950 days = 2 }
        }
    }
}

# Transfer a broken ruler's ordinary secular realm to the Patron. Special ruler identities are
# handled deliberately instead of being treated as ordinary landed titles. scope:domcom_collapse_patron saved.
domcom_ai_resolve_collapse_effect = {
    save_scope_as = domcom_surrendering_subject
    remove_character_flag = domcom_collapse_transferred_titles_this_resolution
    domcom_surrender_prestige_if_lower_effect = yes
    if = { limit = { gold > 0 } pay_short_term_gold = { target = scope:domcom_collapse_patron gold = gold } }

    # Ordinary county/duchy/kingdom/empire holdings transfer normally. Noble Family, Nomad,
    # Head-of-Faith and ceremonial titles are not legal ordinary grants in vanilla and are excluded.
    if = {
        limit = { any_held_title = { domcom_collapse_transferable_title_trigger = yes } }
        add_character_flag = domcom_collapse_transferred_titles_this_resolution
        create_title_and_vassal_change = {
            type = granted
            save_scope_as = domcom_surrender_change
            add_claim_on_loss = yes
        }
        every_held_title = {
            limit = { domcom_collapse_transferable_title_trigger = yes }
            if = {
                limit = { scope:domcom_collapse_patron = { is_ai = no } }
                set_variable = { name = domcom_final_collapse_journal_patron value = scope:domcom_collapse_patron }
            }
            change_title_holder = {
                holder = scope:domcom_collapse_patron
                change = scope:domcom_surrender_change
                government_base = scope:domcom_collapse_patron
            }
        }
        resolve_title_and_vassal_change = scope:domcom_surrender_change
    }

    # Some high secular titles can remain after a government/succession transition. Destroy only
    # titles that were valid collapse property; never destroy protected religious/ceremonial offices.
    if = {
        limit = { any_held_title = { tier >= tier_duchy domcom_collapse_transferable_title_trigger = yes } }
        every_held_title = {
            limit = {
                tier >= tier_duchy
                domcom_collapse_transferable_title_trigger = yes
            }
            add_to_temporary_list = domcom_stuck_titles
        }
        every_in_list = {
            list = domcom_stuck_titles
            save_temporary_scope_as = domcom_stuck_title
            scope:domcom_surrendering_subject = { destroy_title = scope:domcom_stuck_title }
        }
    }

    # Second pass: counties freed by the high-title destruction above still pass to the Patron.
    if = {
        limit = { any_held_title = { domcom_collapse_transferable_title_trigger = yes } }
        add_character_flag = domcom_collapse_transferred_titles_this_resolution
        create_title_and_vassal_change = {
            type = granted
            save_scope_as = domcom_surrender_change_freed
            add_claim_on_loss = yes
        }
        every_held_title = {
            limit = { domcom_collapse_transferable_title_trigger = yes }
            if = {
                limit = { scope:domcom_collapse_patron = { is_ai = no } }
                set_variable = { name = domcom_final_collapse_journal_patron value = scope:domcom_collapse_patron }
            }
            change_title_holder = {
                holder = scope:domcom_collapse_patron
                change = scope:domcom_surrender_change_freed
                government_base = scope:domcom_collapse_patron
            }
        }
        resolve_title_and_vassal_change = scope:domcom_surrender_change_freed
    }

    # EP3 landless adventurers own a camp title/domicile, not ordinary land. Vanilla's own cleanup
    # effect is used so followers, camp state and special troops are not left orphaned.
    if = {
        limit = { is_landless_adventurer = yes }
        destroy_laamp_effect = { ADVENTURER = scope:domcom_surrendering_subject }
    }

    # Administrative/Japanese/Celestial Noble Family titles are house-bound identities. Vanilla
    # refuses to grant/revoke them and its own debug cleanup destroys the title, so Take Everything
    # extinguishes the defeated family's political title instead of putting their Family title on the Patron.
    every_held_title = {
        limit = { is_noble_family_title = yes }
        add_to_temporary_list = domcom_collapse_noble_family_titles
    }
    every_in_list = {
        list = domcom_collapse_noble_family_titles
        save_temporary_scope_as = domcom_collapse_noble_family_title
        scope:domcom_surrendering_subject = { destroy_title = scope:domcom_collapse_noble_family_title }
    }

    # Nomad/Yurt titles are likewise non-grantable personal domicile titles. Dismantle them rather
    # than attempting an illegal title grant. Ordinary conquered counties have already transferred.
    every_held_title = {
        limit = { is_nomad_title = yes }
        add_to_temporary_list = domcom_collapse_nomad_titles
    }
    every_in_list = {
        list = domcom_collapse_nomad_titles
        save_temporary_scope_as = domcom_collapse_nomad_title
        scope:domcom_surrendering_subject = { destroy_title = scope:domcom_collapse_nomad_title }
    }

    if = {
        limit = {
            is_landed = no
            exists = scope:domcom_collapse_patron
            NOT = { is_courtier_of = scope:domcom_collapse_patron }
        }
        set_employer = scope:domcom_collapse_patron
    }

    remove_character_flag = domcom_collapse_pending

    # Only property Dominion actually has authority to confiscate can cause a seizure failure. A
    # surviving Head-of-Faith or ceremonial office is not silently reassigned or destroyed.
    if = {
        limit = { domcom_has_unresolved_collapse_property_trigger = yes }
        add_character_flag = domcom_collapse_seizure_failed
        if = {
            limit = { has_character_modifier = domcom_final_submission_modifier }
            remove_character_modifier = domcom_final_submission_modifier
        }
        # A failed terminal seizure can still have transferred some ordinary titles. Do not leave the
        # temporary Journal marker on those titles if no Final Collapse memory will replace the vanilla one.
        scope:domcom_collapse_patron = {
            every_held_title = {
                limit = {
                    has_variable = domcom_final_collapse_journal_patron
                    var:domcom_final_collapse_journal_patron = scope:domcom_collapse_patron
                }
                remove_variable = domcom_final_collapse_journal_patron
            }
        }
    }
    else = {
        remove_character_flag = domcom_collapse_seizure_failed
        add_character_flag = domcom_collapse_resolved
        add_character_modifier = domcom_final_submission_modifier
        domcom_record_terminal_outcome_effect = { OUTCOME = flag:surrendered }
        scope:domcom_collapse_patron = {
            change_variable = { name = domcom_collapses_resolved add = 1 }
            if = {
                limit = {
                    is_ai = no
                    scope:domcom_surrendering_subject = { has_character_flag = domcom_collapse_transferred_titles_this_resolution }
                }
                create_character_memory = {
                    type = domcom_final_collapse_realm_transfer_memory
                    participants = { submitted_ruler = scope:domcom_surrendering_subject }
                }
                trigger_event = { id = domcom.950 days = 2 }
            }
        }
    }
    remove_character_flag = domcom_collapse_transferred_titles_this_resolution
}


domcom_resolve_bound_ruler_collapse_effect = {
    save_scope_as = domcom_bound_ruler_subject
    domcom_record_terminal_outcome_effect = { OUTCOME = flag:bound_ruler }

    domcom_surrender_prestige_if_lower_effect = yes

    if = {
        limit = { gold > 0 }
        pay_short_term_gold = {
            target = scope:domcom_collapse_patron
            gold = domcom_bound_ruler_treasury_surrender_value
        }
    }

    remove_character_flag = domcom_collapse_pending
    remove_character_flag = domcom_collapse_seizure_failed
    add_character_flag = domcom_collapse_resolved
    add_character_flag = domcom_bound_ruler

    if = {
        limit = { NOT = { has_character_modifier = domcom_final_submission_modifier } }
        add_character_modifier = domcom_final_submission_modifier
    }
    if = {
        limit = { NOT = { has_character_modifier = domcom_bound_ruler_modifier } }
        add_character_modifier = domcom_bound_ruler_modifier
    }

    add_opinion = {
        target = scope:domcom_collapse_patron
        modifier = domcom_bound_ruler_opinion
    }

    scope:domcom_collapse_patron = {
        change_variable = { name = domcom_collapses_resolved add = 1 }
    }
}


# Transfer all positive personal Prestige at terminal collapse when the subject is below the Patron in
# landed rank. Renown is intentionally untouched.
domcom_surrender_prestige_if_lower_effect = {
    save_scope_as = domcom_prestige_subject
    if = {
        limit = {
            prestige > 0
            exists = scope:domcom_collapse_patron
            OR = {
                AND = { is_landed = no scope:domcom_collapse_patron = { is_landed = yes } }
                AND = {
                    is_landed = yes
                    scope:domcom_collapse_patron = { is_landed = yes }
                    highest_held_title_tier < scope:domcom_collapse_patron.highest_held_title_tier
                }
            }
        }
        set_variable = { name = domcom_prestige_surrender value = prestige }
        scope:domcom_collapse_patron = { add_prestige = { value = scope:domcom_prestige_subject.var:domcom_prestige_surrender } }
        add_prestige = { value = var:domcom_prestige_surrender multiply = -1 }
        remove_variable = domcom_prestige_surrender
    }
}


# When a real Final Collapse absorbs an existing Dominion holder, their direct Dominion dependents
# pass upward to the conquering Patron. This is deliberately NOT tied to the cosmetic Power Fantasy
# override: only the genuine terminal-collapse path invokes it.
domcom_absorb_feminized_dependents_effect = {
    save_scope_as = domcom_absorbed_former_patron
    scope:domcom_collapse_patron = { save_scope_as = domcom_absorbing_patron }

    # Use the former Patron's own registries instead of a world-wide living-character scan.
    if = {
        limit = { scope:domcom_absorbed_former_patron = { has_variable_list = domcom_owned_registry } }
        scope:domcom_absorbed_former_patron = {
            every_in_list = {
                variable = domcom_owned_registry
                add_to_temporary_list = domcom_collapse_owned_transfer_list
            }
        }
    }
    every_in_list = {
        list = domcom_collapse_owned_transfer_list
        limit = {
            is_alive = yes
            NOT = { this = scope:domcom_absorbing_patron }
            has_character_flag = domcom_owned_cuck
            has_variable = domcom_patron
            var:domcom_patron = scope:domcom_absorbed_former_patron
        }
        save_scope_as = domcom_absorbed_dependent
        scope:domcom_absorbed_former_patron = {
            if = {
                limit = { has_variable_list = domcom_owned_registry }
                remove_list_variable = { name = domcom_owned_registry target = scope:domcom_absorbed_dependent }
            }
        }
        if = {
            limit = { exists = scope:domcom_absorbed_former_patron.dynasty }
            scope:domcom_absorbed_former_patron.dynasty = {
                if = {
                    limit = { has_variable_list = domcom_owned_subjects }
                    remove_list_variable = { name = domcom_owned_subjects target = scope:domcom_absorbed_dependent }
                }
            }
        }
        scope:domcom_absorbing_patron = { save_scope_as = domcom_owner }
        domcom_own_cuck_generic_effect = yes
    }

    if = {
        limit = { scope:domcom_absorbed_former_patron = { has_variable_list = domcom_pet_registry } }
        scope:domcom_absorbed_former_patron = {
            every_in_list = {
                variable = domcom_pet_registry
                add_to_temporary_list = domcom_collapse_pet_transfer_list
            }
        }
    }
    every_in_list = {
        list = domcom_collapse_pet_transfer_list
        limit = {
            is_alive = yes
            NOT = { this = scope:domcom_absorbing_patron }
            has_character_flag = domcom_pet
            has_variable = domcom_pet_patron
            var:domcom_pet_patron = scope:domcom_absorbed_former_patron
        }
        save_scope_as = domcom_absorbed_dependent
        scope:domcom_absorbed_former_patron = {
            if = {
                limit = { has_variable_list = domcom_pet_registry }
                remove_list_variable = { name = domcom_pet_registry target = scope:domcom_absorbed_dependent }
            }
        }
        set_variable = { name = domcom_pet_patron value = scope:domcom_absorbing_patron }
        set_variable = { name = domcom_obedience_patron value = scope:domcom_absorbing_patron }
        remove_variable = domcom_pet_dynasty
        remove_variable = domcom_pet_number
        scope:domcom_absorbing_patron = { save_scope_as = domcom_tantalize_patron }
        domcom_repair_pet_identity_effect = yes
    }

    # The collapsed former master no longer receives passive benefits from stale lists.
    scope:domcom_absorbed_former_patron = {
        if = { limit = { is_ai = no } domcom_refresh_owned_benefit_tier_effect = yes }
    }
    scope:domcom_absorbing_patron = {
        if = { limit = { is_ai = no } domcom_refresh_owned_benefit_tier_effect = yes }
    }
}

# Male-specific Final Collapse presentation outcome. Political titles remain untouched. The neutral
# domcom_public_remade flag is deliberately future-proof: other gender-specific remaking outcomes can
# reuse the terminal framework without pretending the same presentation has to fit every target.
domcom_resolve_feminized_collapse_effect = {
    save_scope_as = domcom_feminized_subject
    domcom_record_terminal_outcome_effect = { OUTCOME = flag:feminized }
    domcom_surrender_prestige_if_lower_effect = yes

    remove_character_flag = domcom_collapse_pending
    remove_character_flag = domcom_collapse_seizure_failed
    add_character_flag = domcom_collapse_resolved
    add_character_flag = domcom_public_remade
    add_character_flag = domcom_feminized
    set_variable = { name = domcom_feminized_by value = scope:domcom_collapse_patron }

    if = { limit = { NOT = { has_trait = domcom_feminized_trait } } add_trait = domcom_feminized_trait }
    if = { limit = { NOT = { has_character_modifier = domcom_final_submission_modifier } } add_character_modifier = domcom_final_submission_modifier }
    if = { limit = { NOT = { has_character_modifier = domcom_feminized_submission_modifier } } add_character_modifier = domcom_feminized_submission_modifier }

    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 1000 } }
    if = { limit = { var:domcom_cuck_xp < 1000 } set_variable = { name = domcom_cuck_xp value = 1000 } }

    add_opinion = { target = scope:domcom_collapse_patron modifier = domcom_feminized_patron_opinion }
    domcom_refresh_feminized_reputation_effect = yes

    # A conquered master loses their direct Dominion household to the conquering Patron.
    domcom_absorb_feminized_dependents_effect = yes

    scope:domcom_collapse_patron = {
        change_variable = { name = domcom_collapses_resolved add = 1 }
        add_prestige = 150
        add_dread = 5
    }
}

domcom_resolve_devotion_collapse_effect = {
    domcom_record_terminal_outcome_effect = { OUTCOME = flag:devotion }
    domcom_surrender_prestige_if_lower_effect = yes
    remove_character_flag = domcom_collapse_pending
    add_character_flag = domcom_collapse_resolved
    add_character_flag = domcom_absolute_devotion
    add_character_modifier = domcom_absolute_devotion_modifier
    scope:domcom_collapse_patron = { save_scope_as = domcom_communion_patron }
    domcom_apply_communion_tolerance_subject_effect = yes
    add_opinion = { target = scope:domcom_collapse_patron modifier = domcom_final_devotion_opinion }
    scope:domcom_collapse_patron = { change_variable = { name = domcom_collapses_resolved add = 1 } }
}

# Run from the first spouse with scope:domcom_collapsing_spouse and scope:domcom_collapse_patron saved.
domcom_resolve_household_collapse_effect = {
    save_scope_as = domcom_household_collapse_first
    domcom_record_terminal_outcome_effect = { OUTCOME = flag:household }
    domcom_surrender_prestige_if_lower_effect = yes
    remove_character_flag = domcom_collapse_pending
    add_character_flag = domcom_collapse_resolved
    add_character_flag = domcom_household_final
    add_character_modifier = domcom_household_final_modifier
    scope:domcom_collapse_patron = { save_scope_as = domcom_communion_patron }
    domcom_apply_communion_tolerance_subject_effect = yes
    scope:domcom_collapsing_spouse = {
        domcom_record_terminal_outcome_effect = { OUTCOME = flag:household }
        domcom_surrender_prestige_if_lower_effect = yes
        remove_character_flag = domcom_collapse_pending
        add_character_flag = domcom_collapse_resolved
        add_character_flag = domcom_household_final
        add_character_modifier = domcom_household_final_modifier
        domcom_apply_communion_tolerance_subject_effect = yes
    }
    scope:domcom_collapse_patron = {
        change_variable = { name = domcom_collapses_resolved add = 2 }
        change_variable = { name = domcom_household_final_resolutions add = 1 }
    }
}


domcom_check_final_collapse_effect = {
    if = {
        limit = {
            has_character_flag = domcom_owned_cuck
            has_variable = domcom_cuck_xp
            var:domcom_cuck_xp >= 1000
            NOT = { has_character_flag = domcom_collapse_pending }
            NOT = { has_character_flag = domcom_collapse_resolved }
            has_variable = domcom_patron
            var:domcom_patron = { is_alive = yes }
        }
        save_scope_as = domcom_collapsing_subject
        var:domcom_patron = { save_scope_as = domcom_collapse_patron }

        if = {
            limit = { scope:domcom_collapse_patron = { is_ai = no } }
            if = {
                # Everything restores immediate Final Collapse events.
                limit = { has_game_rule = domcom_notifications_everything }
                add_character_flag = domcom_collapse_ready
                domcom_open_final_collapse_event_effect = yes
            }
            else = {
                # Minimal and Strategic both keep Final Collapse queued. Minimal simply excludes prospect
                # alerts, making these collapses the Dominion Pulse's primary interruption.
                if = {
                    limit = { NOT = { has_character_flag = domcom_collapse_ready } }
                    add_character_flag = domcom_collapse_ready
                    scope:domcom_collapse_patron = {
                        if = { limit = { NOT = { has_variable = domcom_collapse_digest_pending } } set_variable = { name = domcom_collapse_digest_pending value = 0 } }
                        change_variable = { name = domcom_collapse_digest_pending add = 1 }
                    }
                }
            }
        }
        else = {
            # AI keeps automatic terminal resolution. v2.4.3 records how often the terminal pipeline is
            # actually reached so a deliberately rare branch can be distinguished from a broken one.
            domcom_ensure_ai_terminal_counters_effect = yes
            change_global_variable = { name = domcom_ai_terminal_decisions_v243 add = 1 }
            if = {
                limit = {
                    is_married = yes
                    any_spouse = {
                        is_alive = yes
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_collapse_patron
                        has_variable = domcom_cuck_xp
                        var:domcom_cuck_xp >= 1000
                        NOT = { has_character_flag = domcom_collapse_pending }
                        NOT = { has_character_flag = domcom_collapse_resolved }
                    }
                }
                every_spouse = {
                    limit = {
                        is_alive = yes
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_collapse_patron
                        has_variable = domcom_cuck_xp
                        var:domcom_cuck_xp >= 1000
                        NOT = { has_character_flag = domcom_collapse_pending }
                        NOT = { has_character_flag = domcom_collapse_resolved }
                    }
                    save_scope_as = domcom_collapsing_spouse
                }
                add_character_flag = domcom_collapse_pending
                scope:domcom_collapsing_spouse = { add_character_flag = domcom_collapse_pending }
                domcom_resolve_household_collapse_effect = yes
            }
            else_if = {
                limit = {
                    OR = {
                        is_consort_of = scope:domcom_collapse_patron
                        has_relation_lover = scope:domcom_collapse_patron
                        has_relation_soulmate = scope:domcom_collapse_patron
                        AND = {
                            has_character_flag = domcom_communion_intimate_bound
                            has_variable = domcom_communion_intimate_patron
                            var:domcom_communion_intimate_patron = scope:domcom_collapse_patron
                        }
                    }
                }
                add_character_flag = domcom_collapse_pending
                domcom_resolve_devotion_collapse_effect = yes
            }
            else = {
                add_character_flag = domcom_collapse_pending
                if = {
                    limit = { any_held_title = { is_noble_family_title = yes } }
                    domcom_resolve_noble_family_conquest_effect = yes
                }
                else = {
                    # v1.6: AI Patrons can choose the same male-specific terminal outcome available to
                    # the player. Previously every AI terminal collapse bypassed Feminization entirely.
                    if = {
                        limit = { is_male = yes age >= 18 }
                        domcom_ensure_ai_terminal_counters_effect = yes
                        change_global_variable = { name = domcom_ai_feminize_eligible_v243 add = 1 }
                        random = {
                            chance = domcom_ai_feminize_collapse_chance_value
                            domcom_resolve_feminized_collapse_effect = yes
                            change_global_variable = { name = domcom_ai_feminize_success_v243 add = 1 }
                        }
                    }
                    if = {
                        limit = { NOT = { has_character_flag = domcom_collapse_resolved } }
                        domcom_ai_resolve_collapse_effect = yes
                    }
                }
            }
        }
    }
}

# Player-facing opener used by the Ledger. It reproduces the old automatic event selection but only
# when the player deliberately presses Collapse.
domcom_open_final_collapse_event_effect = {
    save_scope_as = domcom_collapsing_subject
    var:domcom_patron = { save_scope_as = domcom_collapse_patron }

    if = {
        limit = {
            is_married = yes
            any_spouse = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_collapse_patron
                has_variable = domcom_cuck_xp
                var:domcom_cuck_xp >= 1000
                NOT = { has_character_flag = domcom_collapse_pending }
                NOT = { has_character_flag = domcom_collapse_resolved }
            }
        }
        every_spouse = {
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_collapse_patron
                has_variable = domcom_cuck_xp
                var:domcom_cuck_xp >= 1000
                NOT = { has_character_flag = domcom_collapse_pending }
                NOT = { has_character_flag = domcom_collapse_resolved }
            }
            save_scope_as = domcom_collapsing_spouse
        }
        remove_character_flag = domcom_collapse_ready
        add_character_flag = domcom_collapse_pending
        scope:domcom_collapsing_spouse = { remove_character_flag = domcom_collapse_ready add_character_flag = domcom_collapse_pending }
        scope:domcom_collapse_patron = { trigger_event = { id = domcom.105 days = 1 } }
    }
    else_if = {
        limit = {
            OR = {
                is_consort_of = scope:domcom_collapse_patron
                has_relation_lover = scope:domcom_collapse_patron
                has_relation_soulmate = scope:domcom_collapse_patron
                AND = {
                    has_character_flag = domcom_communion_intimate_bound
                    has_variable = domcom_communion_intimate_patron
                    var:domcom_communion_intimate_patron = scope:domcom_collapse_patron
                }
            }
        }
        remove_character_flag = domcom_collapse_ready
        add_character_flag = domcom_collapse_pending
        scope:domcom_collapse_patron = { trigger_event = { id = domcom.101 days = 1 } }
    }
    else = {
        remove_character_flag = domcom_collapse_ready
        add_character_flag = domcom_collapse_pending
        scope:domcom_collapse_patron = { trigger_event = { id = domcom.100 days = 1 } }
    }
}

# If an Owned subject attacks their Patron and submits while the Patron is defending, the vanilla CB may
# award the defender nothing. Dominion therefore adds a modest capitulation indemnity independent of the
# CB: part of the subject's treasury and prestige plus additional Cuck pressure. Offensive Patron wars
# keep their normal CB reward and do not receive this extra package.
domcom_apply_defensive_capitulation_effect = {
    save_scope_as = domcom_capitulating_subject
    if = {
        # Vanilla War Result deliberately adds no Dominion indemnity; the CB's ordinary defensive result
        # is the entire reward.
        limit = { NOT = { has_game_rule = domcom_capitulation_vanilla } }
        if = {
            limit = { has_game_rule = domcom_capitulation_harsh }
            if = {
                limit = { gold > 0 }
                pay_short_term_gold = { target = scope:domcom_war_patron gold = domcom_harsh_capitulation_gold_value }
            }
            if = {
                limit = { prestige > 0 }
                set_variable = { name = domcom_capitulation_prestige value = domcom_harsh_capitulation_prestige_value }
                scope:domcom_war_patron = { add_prestige = { value = scope:domcom_capitulating_subject.var:domcom_capitulation_prestige } }
                add_prestige = { value = var:domcom_capitulation_prestige multiply = -1 }
                remove_variable = domcom_capitulation_prestige
            }
            if = {
                limit = { has_variable = domcom_cuck_xp }
                change_variable = { name = domcom_cuck_xp add = 200 }
            }
        }
        else = {
            # Indemnities is the default/fallback and exactly preserves v1.7's package.
            if = {
                limit = { gold > 0 }
                pay_short_term_gold = { target = scope:domcom_war_patron gold = domcom_defensive_capitulation_gold_value }
            }
            if = {
                limit = { prestige > 0 }
                set_variable = { name = domcom_capitulation_prestige value = domcom_defensive_capitulation_prestige_value }
                scope:domcom_war_patron = { add_prestige = { value = scope:domcom_capitulating_subject.var:domcom_capitulation_prestige } }
                add_prestige = { value = var:domcom_capitulation_prestige multiply = -1 }
                remove_variable = domcom_capitulation_prestige
            }
            if = {
                limit = { has_variable = domcom_cuck_xp }
                change_variable = { name = domcom_cuck_xp add = 100 }
            }
        }
        if = {
            limit = { has_variable = domcom_cuck_xp }
            if = { limit = { var:domcom_cuck_xp > 1000 } set_variable = { name = domcom_cuck_xp value = 1000 } }
            domcom_refresh_cuck_stage_effect = yes
            if = { limit = { has_character_flag = domcom_owned_cuck } domcom_check_final_collapse_effect = yes }
        }
    }
}

# Successful Dominion over somebody else can rehabilitate an ordinary public Cuck. Owned subjects do
# not escape their Patron by victimizing a third party; they merely claw back 200 Cuck XP. An ordinary
# Cuck loses the public status and receives a two-year grace period before the same continuing scandal
# can register them again.
domcom_reclaim_cucked_standing_effect = {
    if = {
        limit = {
            has_character_flag = domcom_cucked
            NOT = { has_game_rule = domcom_cuck_autonomy_static }
        }
        if = {
            limit = { has_character_flag = domcom_owned_cuck }
            if = {
                limit = { has_game_rule = domcom_cuck_autonomy_dynamic }
                if = { limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp > 450 } change_variable = { name = domcom_cuck_xp subtract = 350 } }
                else = { set_variable = { name = domcom_cuck_xp value = 100 } }
            }
            else = {
                if = { limit = { has_variable = domcom_cuck_xp var:domcom_cuck_xp > 300 } change_variable = { name = domcom_cuck_xp subtract = 200 } }
                else = { set_variable = { name = domcom_cuck_xp value = 100 } }
            }
            if = {
                limit = { has_character_flag = domcom_collapse_ready var:domcom_cuck_xp < 1000 }
                remove_character_flag = domcom_collapse_ready
                if = {
                    limit = { has_variable = domcom_patron }
                    var:domcom_patron = {
                        if = { limit = { has_variable = domcom_collapse_digest_pending var:domcom_collapse_digest_pending > 0 } change_variable = { name = domcom_collapse_digest_pending subtract = 1 } }
                    }
                }
            }
            domcom_refresh_cuck_stage_effect = yes
        }
        else = {
            save_scope_as = domcom_reclaimed_cuck
            if = {
                limit = { has_variable = domcom_cuck_registry_patron }
                var:domcom_cuck_registry_patron = {
                    if = { limit = { has_variable_list = domcom_cucked_registry } remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_reclaimed_cuck } }
                }
            }
            if = { limit = { has_nickname = nick_domcom_the_cucked } remove_nickname = yes }
            remove_character_flag = domcom_cucked
            remove_character_flag = domcom_cuck_registry_added
            remove_character_flag = domcom_global_cuck_registry_added
            remove_character_modifier = domcom_cucked_modifier
            if = { limit = { has_trait = domcom_cucked_trait } remove_trait = domcom_cucked_trait }
            remove_character_modifier = domcom_humiliated_stage_modifier
            remove_character_modifier = domcom_submissive_stage_modifier
            remove_character_modifier = domcom_broken_stage_modifier
            remove_character_modifier = domcom_abject_stage_modifier
            if = {
                limit = { has_variable_list = domcom_compromised_partners }
                every_in_list = {
                    variable = domcom_compromised_partners
                    save_temporary_scope_as = domcom_reclaimed_partner
                    scope:domcom_reclaimed_cuck = { remove_opinion = { target = scope:domcom_reclaimed_partner modifier = domcom_cucked_partner_opinion } }
                    every_child = {
                        save_temporary_scope_as = domcom_reclaimed_partner_child
                        scope:domcom_reclaimed_cuck = { remove_opinion = { target = scope:domcom_reclaimed_partner_child modifier = domcom_cucked_child_opinion } }
                    }
                }
            }
            set_variable = { name = domcom_cuck_xp value = 0 }
            remove_variable = domcom_cuck_patron
            remove_variable = domcom_cuck_registry_patron
            remove_variable = domcom_cuck_origin_patron
            clear_variable_list = domcom_cuck_patrons
            remove_variable = domcom_compromised_partner
            clear_variable_list = domcom_compromised_partners
            if = { limit = { has_game_rule = domcom_cuck_autonomy_dynamic } add_character_flag = { flag = domcom_reclaimed_cuck_recent days = 365 } }
            else = { add_character_flag = { flag = domcom_reclaimed_cuck_recent days = 730 } }
            remove_list_global_variable = { name = domcom_all_cucked target = scope:domcom_reclaimed_cuck }
            every_child = { limit = { is_alive = yes } domcom_refresh_spawn_of_cuck_effect = yes }
        }
    }
}

# Ongoing cuckoldry now has passive momentum. This makes established situations develop without forcing
# the player to repeat Alpha Checks/Taunts simply to make the meter move. Active Lover/Soulmate evidence,
# deep Devotion of a spouse, and a Patron-child in the household each add a small monthly amount.
domcom_monthly_cuck_pressure_for_patron_effect = {
    save_scope_as = domcom_pressure_patron
    if = {
        limit = { has_variable_list = domcom_cucked_registry }
        every_in_list = {
            variable = domcom_cucked_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_cucked
                has_variable = domcom_cuck_patron
                var:domcom_cuck_patron = scope:domcom_pressure_patron
                NOT = { has_character_flag = domcom_collapse_resolved }
            }
            if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
            if = {
                limit = {
                    any_spouse = {
                        is_alive = yes
                        OR = {
                            has_relation_lover = scope:domcom_pressure_patron
                            has_relation_soulmate = scope:domcom_pressure_patron
                            AND = {
                                has_character_flag = domcom_communion_intimate_bound
                                has_variable = domcom_communion_intimate_patron
                                var:domcom_communion_intimate_patron = scope:domcom_pressure_patron
                            }
                        }
                    }
                }
                change_variable = { name = domcom_cuck_xp add = domcom_passive_cuck_bond_xp_value }
            }
            if = {
                limit = {
                    any_spouse = {
                        is_alive = yes
                        has_variable = domcom_obedience_patron
                        var:domcom_obedience_patron = scope:domcom_pressure_patron
                        has_variable = domcom_obedience
                        var:domcom_obedience >= 600
                    }
                }
                change_variable = { name = domcom_cuck_xp add = domcom_passive_cuck_devotion_xp_value }
            }
            if = {
                limit = {
                    any_spouse = {
                        any_child = {
                            OR = {
                                father ?= scope:domcom_pressure_patron
                                mother ?= scope:domcom_pressure_patron
                                real_father ?= scope:domcom_pressure_patron
                            }
                        }
                    }
                }
                change_variable = { name = domcom_cuck_xp add = domcom_passive_cuck_child_xp_value }
            }
            if = { limit = { var:domcom_cuck_xp > 1000 } set_variable = { name = domcom_cuck_xp value = 1000 } }
            domcom_refresh_cuck_stage_effect = yes
            if = { limit = { has_character_flag = domcom_owned_cuck } domcom_check_final_collapse_effect = yes }
        }
    }
}

domcom_monthly_owned_subject_effect = {
    save_scope_as = domcom_monthly_patron
    save_scope_as = domcom_secret_patron
    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_monthly_patron
            }
            if = {
                limit = { monthly_character_income > 0 gold > 0 NOT = { has_character_flag = domcom_tribute_prepaid } }
                pay_short_term_gold = { target = scope:domcom_monthly_patron gold = domcom_monthly_tribute_value }
            }
            domcom_reveal_subject_network_effect = yes
            domcom_refresh_household_dominion_effect = yes
            domcom_check_final_collapse_effect = yes
        }
    }
}


# Run from a Dominion intimate with scope:domcom_communion_patron saved. Only the secret between this
# exact pair is removed; unrelated affairs keep vanilla/Carnalitas consequences.
domcom_clear_communion_pair_secrets_effect = {
    save_scope_as = domcom_communion_partner
    if = {
        limit = {
            exists = scope:domcom_communion_patron
            NOT = { has_character_flag = domcom_allow_adultery_secrets }
        }
        every_secret = {
            type = secret_lover
            limit = { secret_target = scope:domcom_communion_patron }
            remove_secret = yes
        }
        scope:domcom_communion_patron = {
            every_secret = {
                type = secret_lover
                limit = { secret_target = scope:domcom_communion_partner }
                remove_secret = yes
            }
        }
    }
}

# Run from a character whose Lover/Soulmate bond was established by Dominion, with
# scope:domcom_communion_patron saved.
domcom_register_communion_intimate_effect = {
    save_scope_as = domcom_communion_partner
    if = {
        limit = {
            is_alive = yes
            exists = scope:domcom_communion_patron
            NOT = { this = scope:domcom_communion_patron }
            scope:domcom_communion_patron = {
                NOT = {
                    any_in_list = {
                        variable = domcom_intimate_breakup_registry
                        this = scope:domcom_communion_partner
                    }
                }
            }
        }
        add_character_flag = domcom_communion_intimate_bound
        add_character_flag = block_infidelity_flag
        set_variable = { name = domcom_communion_intimate_patron value = scope:domcom_communion_patron }
        scope:domcom_communion_patron = {
            if = {
                limit = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_intimate_registry
                            this = scope:domcom_communion_partner
                        }
                    }
                }
                add_to_variable_list = { name = domcom_intimate_registry target = scope:domcom_communion_partner }
            }
        }
        domcom_clear_communion_pair_secrets_effect = yes
    }
    if = {
        limit = { has_variable = domcom_communion_intimate_patron }
        save_temporary_scope_as = domcom_jealousy_rival
        var:domcom_communion_intimate_patron = { domcom_run_jealousy_pass_effect = yes }
    }
}

domcom_repair_communion_intimates_effect = {
    save_scope_as = domcom_communion_patron

    # Backfill current saves: an existing registered Dominion admirer who is already Lover/Soulmate is
    # authoritative evidence of a consummated bond.
    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        every_in_list = {
            variable = domcom_crush_candidates
            save_temporary_scope_as = domcom_repair_intimate
            limit = {
                is_alive = yes
                scope:domcom_communion_patron = {
                    NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_repair_intimate } }
                }
                has_character_flag = domcom_communion_admirer_registered
                has_variable = domcom_crush_patron
                var:domcom_crush_patron = scope:domcom_communion_patron
                OR = {
                    has_relation_lover = scope:domcom_communion_patron
                    has_relation_soulmate = scope:domcom_communion_patron
                }
            }
            domcom_register_communion_intimate_effect = yes
        }
    }

    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        every_in_list = {
            variable = domcom_crush_candidates
            save_temporary_scope_as = domcom_repair_intimate
            limit = {
                is_alive = yes
                scope:domcom_communion_patron = {
                    NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_repair_intimate } }
                }
                has_character_flag = domcom_communion_admirer_registered
                has_variable = domcom_crush_patron
                var:domcom_crush_patron = scope:domcom_communion_patron
                NOR = {
                    has_relation_crush = scope:domcom_communion_patron
                    has_relation_lover = scope:domcom_communion_patron
                    has_relation_soulmate = scope:domcom_communion_patron
                }
                any_spouse = {
                    is_alive = yes
                    has_character_flag = domcom_cucked
                    OR = {
                        AND = {
                            has_variable = domcom_cuck_patron
                            var:domcom_cuck_patron = scope:domcom_communion_patron
                        }
                        any_in_list = {
                            variable = domcom_cuck_patrons
                            this = scope:domcom_communion_patron
                        }
                    }
                }
            }
            # Do not recreate the vanilla Lover relation here. Re-adding it every time another event
            # removes it creates repeated "fell in love" character-memory/journal entries. The Dominion
            # intimate registry is the durable bond and remains visible/manageable in our Lovers page.
            domcom_register_communion_intimate_effect = yes
        }
    }

    # Persistent repair path used automatically and by the Enforce Dominion GUI.
    if = {
        limit = { has_variable_list = domcom_intimate_registry }
        every_in_list = {
            variable = domcom_intimate_registry
            save_temporary_scope_as = domcom_repair_intimate
            limit = {
                is_alive = yes
                scope:domcom_communion_patron = {
                    NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_repair_intimate } }
                }
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_communion_patron
            }
            # The protected Dominion bond survives a generic vanilla breakup without recreating a
            # vanilla Lover relation. This prevents repeated relationship memories/journal spam.
            domcom_register_communion_intimate_effect = yes
        }
    }
}

# A player-marked protected intimate is intended to survive the character becoming AI/observer. If
# vanilla or a third-party event strips the ordinary Lover relation, monthly Dominion maintenance
# restores it once. Normal deliberate Break Lover still clears the protection first.
domcom_repair_protected_intimates_effect = {
    save_scope_as = domcom_protected_patron
    if = {
        limit = { has_variable_list = domcom_intimate_registry }
        every_in_list = {
            variable = domcom_intimate_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_protected_intimate
                has_variable = domcom_protected_intimate_patron
                var:domcom_protected_intimate_patron = scope:domcom_protected_patron
            }
            save_temporary_scope_as = domcom_protected_partner

            if = {
                limit = {
                    scope:domcom_protected_patron = {
                        NOT = {
                            any_in_list = {
                                variable = domcom_intimate_breakup_registry
                                this = scope:domcom_protected_partner
                            }
                        }
                    }
                }

                # Save migration for pre-2.6.56 Protected Bonds. The old UI promised restoration but
                # only stored a Soulmate marker; ordinary protected Lovers had no restoration marker.
                if = {
                    limit = { NOT = { has_character_flag = domcom_protected_origin_v2656 } }
                    add_character_flag = domcom_protected_origin_v2656
                    if = {
                        limit = { has_character_flag = domcom_protected_was_soulmate }
                        remove_character_flag = domcom_protected_was_lover
                    }
                    else_if = {
                        limit = { has_relation_soulmate = scope:domcom_protected_patron }
                        add_character_flag = domcom_protected_was_soulmate
                        remove_character_flag = domcom_protected_was_lover
                    }
                    else_if = {
                        limit = { has_relation_lover = scope:domcom_protected_patron }
                        add_character_flag = domcom_protected_was_lover
                    }
                    else = {
                        # A legacy protected entry with no surviving vanilla relation is treated as
                        # the ordinary Lover bond the old tooltip promised to restore.
                        add_character_flag = domcom_protected_was_lover
                    }
                }

                # Existing lawful pairings are remembered automatically when an old save first passes
                # through 2.6.56, so a later divorce / Set Aside can be repaired. Spouse and concubine
                # state are kept distinct because CK3 restores them with different effects.
                if = {
                    limit = { is_spouse_of = scope:domcom_protected_patron }
                    add_character_flag = domcom_protected_was_spouse
                    remove_character_flag = domcom_protected_was_concubine
                }
                else_if = {
                    limit = { is_concubine_of = scope:domcom_protected_patron }
                    add_character_flag = domcom_protected_was_concubine
                    remove_character_flag = domcom_protected_was_spouse
                }

                # Restore the actual player-facing vanilla relationship, not only the hidden Dominion
                # registry. Journal cleanup is now separate and quarterly, so protection can do what
                # its tooltip has always claimed.
                if = {
                    limit = {
                        NOR = {
                            has_relation_lover = scope:domcom_protected_patron
                            has_relation_soulmate = scope:domcom_protected_patron
                        }
                        OR = {
                            has_character_flag = domcom_protected_was_soulmate
                            has_character_flag = domcom_protected_was_lover
                        }
                    }
                    if = {
                        limit = { has_character_flag = domcom_protected_was_soulmate }
                        set_relation_soulmate = scope:domcom_protected_patron
                    }
                    else = {
                        set_relation_lover = scope:domcom_protected_patron
                    }
                    add_character_flag = domcom_protected_relation_repaired_this_pass
                }

                # If the protected pair were spouses when protected, a generic divorce no longer silently
                # wins. Re-form the marriage whenever vanilla marriage legality allows it.
                if = {
                    limit = {
                        has_character_flag = domcom_protected_was_spouse
                        NOT = { is_spouse_of = scope:domcom_protected_patron }
                        can_marry_character_trigger = { CHARACTER = scope:domcom_protected_patron }
                    }
                    if = {
                        limit = { scope:domcom_protected_patron = { is_female = yes } }
                        marry_matrilineal = scope:domcom_protected_patron
                    }
                    else = {
                        marry = scope:domcom_protected_patron
                    }
                    add_character_flag = domcom_protected_marriage_repaired_this_pass
                }

                # Concubines/consorts use CK3's separate relation. If a protected concubine was Set Aside,
                # restore that lawful status when the owner still has room and the partner is available.
                if = {
                    limit = {
                        has_character_flag = domcom_protected_was_concubine
                        NOT = { is_consort_of = scope:domcom_protected_patron }
                        is_imprisoned = no
                        is_married = no
                        is_concubine = no
                        scope:domcom_protected_patron = { allowed_more_concubines = yes }
                    }
                    scope:domcom_protected_patron = { make_concubine = scope:domcom_protected_partner }
                    add_character_flag = domcom_protected_marriage_repaired_this_pass
                }

                domcom_register_communion_intimate_effect = yes
                add_character_flag = domcom_communion_intimate_bound
                add_character_flag = block_infidelity_flag

                if = {
                    limit = {
                        OR = {
                            has_character_flag = domcom_protected_relation_repaired_this_pass
                            has_character_flag = domcom_protected_marriage_repaired_this_pass
                        }
                        scope:domcom_protected_patron = { is_ai = no }
                    }
                    scope:domcom_protected_patron = {
                        send_interface_toast = {
                            type = event_toast_effect_good
                            title = DOMCOM_PROTECTED_BOND_REPAIRED_TOAST
                            left_icon = scope:domcom_protected_patron
                            right_icon = scope:domcom_protected_partner
                        }
                    }
                }
                remove_character_flag = domcom_protected_relation_repaired_this_pass
                remove_character_flag = domcom_protected_marriage_repaired_this_pass
            }
        }
    }
}

domcom_consummate_admirer_effect = {
    # 2.5.1: AI prospect/tribute consummation is another autonomous sex-equivalent path. If the
    # prospective partner belongs to a human player's household, warn and queue the confrontation instead
    # of silently creating a Lover/pregnancy.
    if = {
        limit = {
            scope:domcom_admirer_patron = { is_ai = yes }
            NOT = { is_consort_of = scope:domcom_admirer_patron }
            any_consort = {
                is_alive = yes
                age >= 18
                is_ai = no
                NOT = { this = scope:domcom_admirer_patron }
            }
        }
        add_character_flag = domcom_admirer_intercepted_by_guard
        scope:domcom_admirer_patron = { save_scope_as = domcom_tantalize_patron }
        domcom_queue_ai_courtship_against_player_effect = yes
    }
    else = {
    save_scope_as = domcom_admirer_partner
    if = {
        limit = {
            NOT = { has_relation_lover = scope:domcom_admirer_patron }
            scope:domcom_admirer_patron = {
                NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_admirer_partner } }
            }
        }
        set_relation_lover = scope:domcom_admirer_patron
    }
    scope:domcom_admirer_patron = { save_scope_as = domcom_communion_patron }
    if = {
        limit = {
            scope:domcom_admirer_patron = {
                NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_admirer_partner } }
            }
        }
        domcom_register_communion_intimate_effect = yes
    }
    if = {
        limit = {
            is_female = yes is_visibly_fertile = yes is_pregnant = no
            scope:domcom_admirer_patron = { is_male = yes is_visibly_fertile = yes }
        }
        make_pregnant = { father = scope:domcom_admirer_patron number_of_children = 1 known_bastard = no }
    }
    else_if = {
        limit = {
            is_male = yes is_visibly_fertile = yes
            scope:domcom_admirer_patron = { is_female = yes is_visibly_fertile = yes is_pregnant = no }
        }
        scope:domcom_admirer_patron = { make_pregnant = { father = scope:domcom_admirer_partner number_of_children = 1 known_bastard = no } }
    }
    scope:domcom_admirer_patron = { change_variable = { name = domcom_admirer_nights add = 1 } }

    }
}

domcom_try_admirer_approach_effect = {
    save_scope_as = domcom_approach_patron

    # Human players are no longer interrupted once per month. Successful attraction checks remain
    # registered on Dynastic Prospects and can be acted on deliberately with Receive/Receive All.
    # AI patrons retain autonomous approaches.
    if = {
        limit = { is_ai = yes has_variable_list = domcom_crush_candidates }
        random_in_list = {
            variable = domcom_crush_candidates
            limit = {
                is_alive = yes
                age >= 18
                has_variable = domcom_crush_patron
                var:domcom_crush_patron = scope:domcom_approach_patron
                has_relation_crush = scope:domcom_approach_patron
                NOT = { is_consort_of = scope:domcom_approach_patron }
                NOT = { has_character_flag = domcom_household_guarded }
                NOT = { has_relation_lover = scope:domcom_approach_patron }
                NOT = { has_relation_soulmate = scope:domcom_approach_patron }
            }
            save_scope_as = domcom_admirer
        }
        if = {
            limit = { exists = scope:domcom_admirer }
            random = {
                chance = 35
                scope:domcom_admirer = {
                    scope:domcom_approach_patron = { save_scope_as = domcom_admirer_patron }
                    domcom_consummate_admirer_effect = yes
                    if = { limit = { has_character_flag = domcom_admirer_intercepted_by_guard } remove_character_flag = domcom_admirer_intercepted_by_guard }
                }
            }
        }
    }
}

domcom_record_displaced_blood_heir_effect = {
    save_scope_as = domcom_blood_child

    if = {
        limit = {
            exists = father
            NOT = { father ?= scope:domcom_ack_patron }
            father = {
                is_alive = yes
                is_landed = yes
                OR = {
                    AND = {
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_ack_patron
                    }
                    AND = {
                        has_character_flag = domcom_cucked
                        has_variable = domcom_cuck_patron
                        var:domcom_cuck_patron = scope:domcom_ack_patron
                    }
                }
                OR = {
                    NOT = { has_variable = domcom_blood_successor }
                    var:domcom_blood_successor = { is_alive = no }
                }
                exists = primary_heir
                primary_heir = { this = scope:domcom_blood_child }
            }
        }
        father = {
            save_scope_as = domcom_displaced_cuck
            set_variable = { name = domcom_blood_successor value = scope:domcom_blood_child }
            primary_title = { save_scope_as = domcom_displaced_primary_title }
        }
        set_variable = { name = domcom_displaced_cuck value = scope:domcom_displaced_cuck }
        set_variable = { name = domcom_displaced_claim_title value = scope:domcom_displaced_primary_title }
        add_pressed_claim = scope:domcom_displaced_primary_title
    }
    else_if = {
        limit = {
            exists = mother
            NOT = { mother ?= scope:domcom_ack_patron }
            mother = {
                is_alive = yes
                is_landed = yes
                OR = {
                    AND = {
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_ack_patron
                    }
                    AND = {
                        has_character_flag = domcom_cucked
                        has_variable = domcom_cuck_patron
                        var:domcom_cuck_patron = scope:domcom_ack_patron
                    }
                }
                OR = {
                    NOT = { has_variable = domcom_blood_successor }
                    var:domcom_blood_successor = { is_alive = no }
                }
                exists = primary_heir
                primary_heir = { this = scope:domcom_blood_child }
            }
        }
        mother = {
            save_scope_as = domcom_displaced_cuck
            set_variable = { name = domcom_blood_successor value = scope:domcom_blood_child }
            primary_title = { save_scope_as = domcom_displaced_primary_title }
        }
        set_variable = { name = domcom_displaced_cuck value = scope:domcom_displaced_cuck }
        set_variable = { name = domcom_displaced_claim_title value = scope:domcom_displaced_primary_title }
        add_pressed_claim = scope:domcom_displaced_primary_title
    }
}

domcom_react_to_acknowledged_blood_heir_effect = {
    save_scope_as = domcom_blood_cuck
    if = {
        limit = {
            is_ai = yes
            has_variable = domcom_blood_successor
            var:domcom_blood_successor = { is_alive = yes }
        }
        var:domcom_blood_successor = { save_scope_as = domcom_blood_child }

        random = {
            chance = domcom_blood_heir_retaliation_chance_value
            random_list = {
                62 = {
                    scope:domcom_blood_child = {
                        add_character_flag = domcom_blood_repudiated_by_cuck
                        if = {
                            limit = { has_variable = domcom_displaced_claim_title }
                            var:domcom_displaced_claim_title = { save_scope_as = domcom_repudiated_title }
                            if = {
                                limit = { has_claim_on = scope:domcom_repudiated_title }
                                remove_claim = scope:domcom_repudiated_title
                            }
                        }
                        add_opinion = { target = scope:domcom_blood_cuck modifier = domcom_blood_heir_persecuted_opinion }
                    }
                    add_opinion = { target = scope:domcom_blood_child modifier = domcom_blood_heir_repudiated_opinion }
                    scope:domcom_blood_patron = {
                        send_interface_toast = {
                            type = event_toast_effect_bad
                            title = domcom_blood_heir_repudiated_toast
                            left_icon = scope:domcom_blood_child
                            right_icon = scope:domcom_blood_cuck
                        }
                    }
                }
                28 = {
                    trigger = {
                        scope:domcom_blood_child = {
                            is_alive = yes
                            is_imprisoned = no
                            OR = {
                                is_courtier_of = scope:domcom_blood_cuck
                                is_vassal_of = scope:domcom_blood_cuck
                            }
                        }
                    }
                    imprison = { target = scope:domcom_blood_child type = house_arrest }
                    scope:domcom_blood_child = {
                        add_character_flag = domcom_blood_imprisoned_by_cuck
                        add_opinion = { target = scope:domcom_blood_cuck modifier = domcom_blood_heir_persecuted_opinion }
                    }
                    scope:domcom_blood_patron = {
                        send_interface_toast = {
                            type = event_toast_effect_bad
                            title = domcom_blood_heir_imprisoned_toast
                            left_icon = scope:domcom_blood_child
                            right_icon = scope:domcom_blood_cuck
                        }
                    }
                }
                10 = {
                    trigger = {
                        OR = {
                            has_trait = sadistic
                            has_trait = vengeful
                            has_trait = wrathful
                            has_trait = paranoid
                        }
                        scope:domcom_blood_child = {
                            is_alive = yes
                            OR = {
                                is_courtier_of = scope:domcom_blood_cuck
                                is_vassal_of = scope:domcom_blood_cuck
                            }
                        }
                    }
                    scope:domcom_blood_child = {
                        death = { death_reason = death_murder killer = scope:domcom_blood_cuck }
                    }
                    scope:domcom_blood_patron = {
                        send_interface_toast = {
                            type = event_toast_effect_bad
                            title = domcom_blood_heir_murdered_toast
                            left_icon = scope:domcom_blood_patron
                            right_icon = scope:domcom_blood_cuck
                        }
                    }
                }
            }
        }
    }
}

# Acknowledge one child. Run from child with scope:domcom_ack_patron saved.
domcom_acknowledge_child_effect = {
    # This must run before set_father/set_house: those effects can immediately alter the child's vanilla
    # place in the Owned subject's succession.
    domcom_record_displaced_blood_heir_effect = yes

    if = { limit = { real_father ?= scope:domcom_ack_patron } set_father = scope:domcom_ack_patron }
    if = { limit = { exists = scope:domcom_ack_patron.house } set_house = scope:domcom_ack_patron.house }
    add_opinion = { target = scope:domcom_ack_patron modifier = domcom_acknowledged_blood_opinion }
    remove_character_flag = domcom_hidden_blood_child
    add_character_flag = domcom_blood_acknowledged_child
    save_temporary_scope_as = domcom_acked_child
    scope:domcom_ack_patron = {
        if = {
            limit = { has_variable_list = domcom_blood_registry }
            remove_list_variable = { name = domcom_blood_registry target = scope:domcom_acked_child }
        }
    }
    domcom_refresh_spawn_of_cuck_effect = yes
    scope:domcom_ack_patron = {
        domcom_initialize_ledger_counters_effect = yes
        change_variable = { name = domcom_blood_acknowledged add = 1 }
    }

    if = {
        limit = {
            has_variable = domcom_displaced_cuck
            var:domcom_displaced_cuck = { is_alive = yes }
        }
        save_scope_as = domcom_blood_child
        scope:domcom_ack_patron = { save_scope_as = domcom_blood_patron }
        var:domcom_displaced_cuck = { save_scope_as = domcom_blood_cuck }

        scope:domcom_ack_patron = {
            send_interface_toast = {
                type = event_toast_effect_neutral
                title = domcom_blood_heir_recorded_toast
                left_icon = scope:domcom_blood_child
                right_icon = scope:domcom_blood_cuck
            }
        }
        scope:domcom_blood_cuck = { domcom_react_to_acknowledged_blood_heir_effect = yes }
    }
}

domcom_acknowledge_all_blood_effect = {
    save_scope_as = domcom_ack_patron
    if = {
        limit = { has_variable_list = domcom_ui_blood_children }
        every_in_list = {
            variable = domcom_ui_blood_children
            limit = {
                is_alive = yes
                real_father ?= scope:domcom_ack_patron
                NOT = { father ?= scope:domcom_ack_patron }
                NOT = { has_character_flag = domcom_blood_acknowledged_child }
            }
            domcom_acknowledge_child_effect = yes
        }
    }
}

# Abdicate an Owned ruler in favor of an acknowledged child of the patron. Run from recipient with
# scope:domcom_abdication_patron saved.
domcom_abdicate_to_blood_effect = {
    save_scope_as = domcom_abdicating_subject

    if = {
        limit = {
            has_variable = domcom_blood_successor
            var:domcom_blood_successor = { is_alive = yes }
        }
        var:domcom_blood_successor = { save_scope_as = domcom_blood_successor }
    }
    else = {
        primary_heir = { save_scope_as = domcom_blood_successor }
    }

    # A successful demand also frees the designated child if this same subject imprisoned them in
    # retaliation.
    scope:domcom_blood_successor = {
        if = {
            limit = { is_imprisoned = yes imprisoner ?= scope:domcom_abdicating_subject }
            release_from_prison = yes
        }
    }

    create_title_and_vassal_change = {
        type = granted
        save_scope_as = domcom_blood_abdication_change
        add_claim_on_loss = yes
    }
    every_held_title = {
        limit = {
            NOT = { tier = tier_barony }
            NOT = { is_landless_type_title = yes }
        }
        change_title_holder = {
            holder = scope:domcom_blood_successor
            change = scope:domcom_blood_abdication_change
            government_base = scope:domcom_blood_successor
        }
    }
    resolve_title_and_vassal_change = scope:domcom_blood_abdication_change
    if = { limit = { has_variable = domcom_blood_successor } remove_variable = domcom_blood_successor }

    change_variable = { name = domcom_cuck_xp add = 250 }
    domcom_refresh_cuck_stage_effect = yes
    scope:domcom_abdication_patron = {
        domcom_initialize_ledger_counters_effect = yes
        change_variable = { name = domcom_abdications_for_blood add = 1 }
    }
}

# AI parity: once per random yearly playable pulse, an eligible AI ruler looks at consorts of existing
# lovers/soulmates and may attempt the same Alpha Check.
domcom_ai_seek_dominion_effect = {
    save_scope_as = domcom_ai_patron
    every_relation = {
        type = lover
        type = soulmate
        limit = {
            is_alive = yes
            age >= 18
            NOT = { has_character_flag = domcom_household_guarded }
        }
        every_consort = {
            limit = {
                is_alive = yes age >= 18
                NOT = { this = scope:domcom_ai_patron }
                sex_same_as = scope:domcom_ai_patron
                NOT = { has_character_flag = domcom_owned_cuck }
                OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ai_patron }
            }
            add_to_temporary_list = domcom_ai_cuck_targets
        }
    }
    every_child = {
        if = {
            limit = { father ?= scope:domcom_ai_patron exists = mother }
            mother = {
                every_consort = {
                    limit = {
                        is_alive = yes age >= 18 NOT = { this = scope:domcom_ai_patron }
                        sex_same_as = scope:domcom_ai_patron
                        NOT = { has_character_flag = domcom_owned_cuck }
                        OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ai_patron }
                    }
                    add_to_temporary_list = domcom_ai_cuck_targets
                }
            }
        }
        else_if = {
            limit = { real_father ?= scope:domcom_ai_patron exists = mother }
            mother = {
                every_consort = {
                    limit = {
                        is_alive = yes age >= 18 NOT = { this = scope:domcom_ai_patron }
                        sex_same_as = scope:domcom_ai_patron
                        NOT = { has_character_flag = domcom_owned_cuck }
                        OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ai_patron }
                    }
                    add_to_temporary_list = domcom_ai_cuck_targets
                }
            }
        }
        else_if = {
            limit = { mother ?= scope:domcom_ai_patron exists = father }
            father = {
                every_consort = {
                    limit = {
                        is_alive = yes age >= 18 NOT = { this = scope:domcom_ai_patron }
                        sex_same_as = scope:domcom_ai_patron
                        NOT = { has_character_flag = domcom_owned_cuck }
                        OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ai_patron }
                    }
                    add_to_temporary_list = domcom_ai_cuck_targets
                }
            }
        }
    }

    # Optional Carnalitas evidence: actual one-off sex with a spouse/consort or soulmate can create a
    # target even if no Lover relationship or child exists.
    if = {
        limit = { has_variable_list = domcom_sex_cuck_targets }
        every_in_list = {
            variable = domcom_sex_cuck_targets
            limit = {
                is_alive = yes age >= 18
                NOT = { this = scope:domcom_ai_patron }
                sex_same_as = scope:domcom_ai_patron
                NOT = { has_character_flag = domcom_owned_cuck }
                OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ai_patron }
                any_in_list = {
                    variable = domcom_sex_evidence_patrons
                    this = scope:domcom_ai_patron
                }
            }
            add_to_temporary_list = domcom_ai_cuck_targets
        }
    }

    random_in_list = {
        list = domcom_ai_cuck_targets
        save_scope_as = domcom_ai_cuck_target
        # 2.5.1: relationship labels are prospective evidence, not public cuckoldry. This helper either
        # consumes already-real sex/parentage evidence, queues the human spouse confrontation, or makes
        # an actual AI-vs-AI intimacy roll before applying the Cucked state.
        domcom_ai_resolve_relationship_dominion_target_effect = yes
    }
}

# AI patrons occasionally use an available humiliation partner against an Owned subject.
domcom_ai_try_public_humiliation_effect = {
    save_scope_as = domcom_public_patron
    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        random_in_list = {
            variable = domcom_crush_candidates
            limit = {
                is_alive = yes age >= 18
                OR = {
                    has_relation_crush = scope:domcom_public_patron
                    has_relation_lover = scope:domcom_public_patron
                    has_relation_soulmate = scope:domcom_public_patron
                }
                OR = {
                    any_spouse = {
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_public_patron
                    }
                    AND = {
                        has_variable = domcom_crush_source
                        var:domcom_crush_source = {
                            is_alive = yes
                            has_character_flag = domcom_owned_cuck
                            has_variable = domcom_patron
                            var:domcom_patron = scope:domcom_public_patron
                        }
                    }
                }
            }
            save_scope_as = domcom_ai_public_partner
        }
        if = {
            limit = { exists = scope:domcom_ai_public_partner }
            scope:domcom_ai_public_partner = {
                random_spouse = {
                    limit = {
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_public_patron
                    }
                    save_scope_as = domcom_humiliated_cuck
                }
                if = {
                    limit = {
                        NOT = { exists = scope:domcom_humiliated_cuck }
                        has_variable = domcom_crush_source
                    }
                    var:domcom_crush_source = {
                        if = {
                            limit = {
                                is_alive = yes
                                has_character_flag = domcom_owned_cuck
                                has_variable = domcom_patron
                                var:domcom_patron = scope:domcom_public_patron
                            }
                            save_scope_as = domcom_humiliated_cuck
                        }
                    }
                }
                if = {
                    limit = { exists = scope:domcom_humiliated_cuck }
                    domcom_apply_public_humiliation_generic_effect = yes
                }
            }
        }
    }
}

# Called from on_birth_child. It cannot intercept every vanilla sex event, but it can enforce the
# Dominion interpretation on detectable marital conception.
domcom_process_dominion_summons_birth_effect = {
    save_scope_as = domcom_summons_child
    if = { limit = { exists = mother } mother = { save_scope_as = domcom_birth_mother } }
    if = { limit = { exists = father } father = { save_scope_as = domcom_birth_father } }

    # Most complete case: a male cucked/Owned father is publicly recorded as the father after marital
    # sex. The patron is substituted as the hidden real father.
    if = {
        limit = {
            exists = father exists = mother
            father = {
                is_married = yes
                OR = { has_variable = domcom_patron has_variable = domcom_cuck_patron }
                is_spouse_of = scope:domcom_birth_mother
            }
        }
        father = {
            if = {
                limit = { has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_summons_patron }
            }
            else_if = {
                limit = { has_variable = domcom_cuck_patron }
                var:domcom_cuck_patron = { save_scope_as = domcom_summons_patron }
            }
            save_scope_as = domcom_summons_cuck
        }
        if = {
            limit = { exists = scope:domcom_summons_patron scope:domcom_summons_patron = { is_alive = yes is_male = yes } }
            set_real_father = scope:domcom_summons_patron
            add_character_flag = domcom_hidden_blood_child
            scope:domcom_summons_cuck = {
                change_variable = { name = domcom_cuck_xp add = 150 }
                domcom_refresh_cuck_stage_effect = yes
            }
            scope:domcom_summons_patron = {
                change_variable = { name = domcom_summons_claimed add = 1 }
                if = {
                    limit = { is_ai = no }
                    send_interface_toast = {
                        type = event_toast_effect_neutral
                        title = domcom_summons_toast
                        left_icon = scope:domcom_summons_patron
                        right_icon = scope:domcom_summons_cuck
                    }
                }
            }
        }
    }

    # Other sex/orientation configurations cannot always be rewritten into valid CK3 genealogy. They
    # still count as a Dominion summons when the save exposes a marital conception involving a cucked
    # spouse.
    if = {
        limit = {
            exists = mother exists = father
            mother = {
                is_married = yes
                OR = { has_variable = domcom_patron has_variable = domcom_cuck_patron }
                is_spouse_of = scope:domcom_birth_father
            }
        }
        mother = {
            if = {
                limit = { has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_summons_patron_two }
            }
            else_if = {
                limit = { has_variable = domcom_cuck_patron }
                var:domcom_cuck_patron = { save_scope_as = domcom_summons_patron_two }
            }
            save_scope_as = domcom_summons_cuck_two
        }
        if = {
            limit = { exists = scope:domcom_summons_patron_two scope:domcom_summons_patron_two = { is_alive = yes } }
            scope:domcom_summons_cuck_two = {
                change_variable = { name = domcom_cuck_xp add = 100 }
                domcom_refresh_cuck_stage_effect = yes
            }
            scope:domcom_summons_patron_two = { change_variable = { name = domcom_summons_claimed add = 1 } }
        }
    }
}


domcom_try_tantalize_intimacy_effect = {
    save_scope_as = domcom_tantalize_partner

    # 2.5.1: autonomous AI cannot jump directly from a successful Tantalize to sex with a human
    # player's spouse/concubine/consort. The courtship warning queues a later duel/chess intervention.
    if = {
        limit = {
            scope:domcom_tantalize_patron = { is_ai = yes }
            any_consort = {
                is_alive = yes
                age >= 18
                is_ai = no
                NOT = { this = scope:domcom_tantalize_patron }
            }
        }
        domcom_queue_ai_courtship_against_player_effect = yes
    }
    else = {
        if = {
            limit = { has_relation_soulmate = scope:domcom_tantalize_patron }
            random = { chance = 40 add_character_flag = domcom_tantalize_became_intimate }
        }
        else_if = {
            limit = { has_relation_lover = scope:domcom_tantalize_patron }
            random = { chance = 30 add_character_flag = domcom_tantalize_became_intimate }
        }
        else = {
            # A first successful Tantalize normally creates a Crush; only a minority of those encounters
            # immediately become sexual.
            random = { chance = 12 add_character_flag = domcom_tantalize_became_intimate }
        }

        if = {
            limit = { has_character_flag = domcom_tantalize_became_intimate }
            remove_character_flag = domcom_tantalize_became_intimate

            # The direct Dominion path owns this Mastery award. If Carnalitas also observes the vanilla sex
            # effect, this synchronous guard keeps carn_on_sex_v2 from awarding the same encounter twice.
            add_character_flag = domcom_mastery_direct_sex_guard
            scope:domcom_tantalize_patron = { add_character_flag = domcom_mastery_direct_sex_guard }

            scope:domcom_tantalize_patron = {
                had_sex_with_effect = {
                    CHARACTER = scope:domcom_tantalize_partner
                    PREGNANCY_CHANCE = pregnancy_chance
                }
                save_scope_as = domcom_direct_sex_patron
            }

            remove_character_flag = domcom_mastery_direct_sex_guard
            scope:domcom_tantalize_patron = { remove_character_flag = domcom_mastery_direct_sex_guard }
            if = { limit = { is_male = yes age >= 18 } domcom_endowment_mastery_direct_positive_sex_effect = yes }
            if = { limit = { is_female = yes age >= 18 } domcom_breast_mastery_direct_positive_sex_effect = yes }
            scope:domcom_tantalize_patron = {
                if = { limit = { is_male = yes age >= 18 } domcom_endowment_mastery_direct_positive_sex_effect = yes }
                if = { limit = { is_female = yes age >= 18 } domcom_breast_mastery_direct_positive_sex_effect = yes }
            }

            domcom_record_direct_dominion_sex_effect = yes
            scope:domcom_tantalize_patron = {
                if = {
                    limit = { is_ai = no }
                    send_interface_toast = {
                        type = event_toast_effect_good
                        title = domcom_tantalize_intimate_toast
                        left_icon = scope:domcom_tantalize_patron
                        right_icon = scope:domcom_tantalize_partner
                    }
                }
            }
        }
    }
}

domcom_break_up_with_lover_effect = {
    save_scope_as = domcom_breakup_partner
    if = {
        limit = {
            exists = scope:domcom_breakup_patron
            NOT = { this = scope:domcom_breakup_patron }
        }

        # Record the player's deliberate choice before removing the relationship.
        scope:domcom_breakup_patron = {
            if = {
                limit = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_intimate_breakup_registry
                            this = scope:domcom_breakup_partner
                        }
                    }
                }
                add_to_variable_list = { name = domcom_intimate_breakup_registry target = scope:domcom_breakup_partner }
            }
            if = {
                limit = { has_variable_list = domcom_intimate_registry }
                remove_list_variable = { name = domcom_intimate_registry target = scope:domcom_breakup_partner }
            }
            if = {
                limit = { has_variable_list = domcom_crush_candidates }
                remove_list_variable = { name = domcom_crush_candidates target = scope:domcom_breakup_partner }
            }
        }

        if = { limit = { has_relation_soulmate = scope:domcom_breakup_patron } remove_relation_soulmate = scope:domcom_breakup_patron }
        if = { limit = { has_relation_lover = scope:domcom_breakup_patron } remove_relation_lover = scope:domcom_breakup_patron }
        if = { limit = { has_relation_crush = scope:domcom_breakup_patron } remove_relation_crush = scope:domcom_breakup_patron }

        # Only clear the persistent intimate metadata when it belongs to this Patron. Other Dominion/AI
        # pairings are not touched.
        if = {
            limit = {
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_breakup_patron
            }
            remove_character_flag = domcom_communion_intimate_bound
            remove_character_flag = block_infidelity_flag
            remove_variable = domcom_communion_intimate_patron
            if = {
                limit = {
                    has_character_flag = domcom_protected_intimate
                    has_variable = domcom_protected_intimate_patron
                    var:domcom_protected_intimate_patron = scope:domcom_breakup_patron
                }
                remove_character_flag = domcom_protected_intimate
                remove_character_flag = domcom_protected_was_soulmate
                remove_character_flag = domcom_protected_was_lover
                remove_character_flag = domcom_protected_was_spouse
                remove_character_flag = domcom_protected_was_concubine
                remove_character_flag = domcom_protected_origin_v2656
                remove_variable = domcom_protected_intimate_patron
            }
        }
        if = {
            limit = {
                has_variable = domcom_crush_patron
                var:domcom_crush_patron = scope:domcom_breakup_patron
            }
            remove_variable = domcom_crush_patron
        }
    }
}

# Run from the Patron. Copy the current relationship graph to a temporary list first so relation removal
# never mutates the iterator being traversed.
domcom_break_up_with_all_lovers_effect = {
    save_scope_as = domcom_breakup_patron
    clear_variable_list = domcom_breakup_batch

    every_relation = {
        type = lover
        type = soulmate
        limit = { is_alive = yes NOT = { this = scope:domcom_breakup_patron } }
        save_temporary_scope_as = domcom_breakup_candidate
        scope:domcom_breakup_patron = {
            if = {
                limit = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_breakup_batch
                            this = scope:domcom_breakup_candidate
                        }
                    }
                }
                add_to_variable_list = { name = domcom_breakup_batch target = scope:domcom_breakup_candidate }
            }
        }
    }


    # Include bonds whose vanilla Lover relation was removed by an outside event.
    if = {
        limit = { has_variable_list = domcom_intimate_registry }
        every_in_list = {
            variable = domcom_intimate_registry
            limit = {
                is_alive = yes
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_breakup_patron
            }
            save_temporary_scope_as = domcom_breakup_candidate
            scope:domcom_breakup_patron = {
                if = {
                    limit = { NOT = { any_in_list = { variable = domcom_breakup_batch this = scope:domcom_breakup_candidate } } }
                    add_to_variable_list = { name = domcom_breakup_batch target = scope:domcom_breakup_candidate }
                }
            }
        }
    }

    if = {
        limit = { has_variable_list = domcom_breakup_batch }
        every_in_list = {
            variable = domcom_breakup_batch
            domcom_break_up_with_lover_effect = yes
        }
    }
    clear_variable_list = domcom_breakup_batch
}

domcom_apply_communion_tolerance_subject_effect = {
    save_scope_as = domcom_communion_partner
    if = {
        limit = {
            is_alive = yes
            exists = scope:domcom_communion_patron
            OR = {
                has_character_flag = domcom_owned_cuck
                has_character_flag = domcom_household_dominion
                has_character_flag = domcom_absolute_devotion
                has_character_flag = domcom_household_final
            }
        }
        add_character_flag = domcom_accepts_communion
        if = {
            limit = { NOT = { has_character_modifier = domcom_accepts_communion_modifier } }
            add_character_modifier = domcom_accepts_communion_modifier
        }
        add_opinion = { target = scope:domcom_communion_patron modifier = domcom_communion_acceptance_opinion }

        # Remember and protect only an actual Dominion Lover/Soulmate bond. Marriage by itself is never
        # converted into a lover relationship.
        if = {
            limit = {
                OR = {
                    has_relation_lover = scope:domcom_communion_patron
                    has_relation_soulmate = scope:domcom_communion_patron
                }
                scope:domcom_communion_patron = {
                    NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_communion_partner } }
                }
            }
            domcom_register_communion_intimate_effect = yes
        }

        # If a generic event removes the vanilla Lover/Soulmate relation, keep Dominion's own intimate
        # bond instead of recreating the vanilla relation. Repeated set_relation_lover calls generate
        # repeated "fell in love" memories in the character journal.
        if = {
            limit = {
                has_character_flag = domcom_communion_intimate_bound
                NOR = {
                    has_relation_lover = scope:domcom_communion_patron
                    has_relation_soulmate = scope:domcom_communion_patron
                }
                scope:domcom_communion_patron = {
                    NOT = { any_in_list = { variable = domcom_intimate_breakup_registry this = scope:domcom_communion_partner } }
                }
            }
            domcom_register_communion_intimate_effect = yes
        }
    }
}

domcom_repair_cuck_integrity_096_effect = {
    save_scope_as = domcom_integrity_viewer
    clear_variable_list = domcom_integrity_purge_queue

    if = {
        limit = {
            is_ai = no
            NOT = { has_character_flag = domcom_cuck_integrity_repaired_096 }
        }
        add_character_flag = domcom_cuck_integrity_repaired_096

        if = {
            limit = { has_global_variable_list = domcom_all_cucked }
            every_in_global_list = {
                variable = domcom_all_cucked
                limit = { is_alive = yes has_character_flag = domcom_cucked }
                save_temporary_scope_as = domcom_integrity_subject

                # Repair visible overflow before judging the record.
                domcom_refresh_cuck_stage_effect = yes

                # Self-attribution is impossible. Clear every legacy pointer that identifies the victim
                # as their own Patron/cucker.
                if = {
                    limit = {
                        has_variable = domcom_cuck_origin_patron
                        var:domcom_cuck_origin_patron = scope:domcom_integrity_subject
                    }
                    remove_variable = domcom_cuck_origin_patron
                }
                if = {
                    limit = {
                        has_variable = domcom_cuck_patron
                        var:domcom_cuck_patron = scope:domcom_integrity_subject
                    }
                    remove_variable = domcom_cuck_patron
                }
                if = {
                    limit = {
                        has_variable = domcom_cuck_registry_patron
                        var:domcom_cuck_registry_patron = scope:domcom_integrity_subject
                    }
                    remove_variable = domcom_cuck_registry_patron
                }
                if = {
                    limit = {
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_integrity_subject
                    }
                    remove_variable = domcom_patron
                    remove_character_flag = domcom_owned_cuck
                    remove_character_modifier = domcom_owned_modifier
                }

                # Remove impossible self entries from historical/evidence lists.
                if = {
                    limit = { has_variable_list = domcom_cuck_patrons }
                    remove_list_variable = { name = domcom_cuck_patrons target = scope:domcom_integrity_subject }
                }
                if = {
                    limit = { has_variable_list = domcom_sex_evidence_patrons }
                    remove_list_variable = { name = domcom_sex_evidence_patrons target = scope:domcom_integrity_subject }
                }
                if = {
                    limit = { has_variable_list = domcom_betrayal_evidence_patrons }
                    remove_list_variable = { name = domcom_betrayal_evidence_patrons target = scope:domcom_integrity_subject }
                }

                # Reconstruct only from surviving evidence. Strong explicit sex evidence is preferred
                # over later/current ownership pointers.
                if = {
                    limit = {
                        NOT = { has_variable = domcom_cuck_origin_patron }
                        has_variable_list = domcom_sex_evidence_patrons
                    }
                    every_in_list = {
                        variable = domcom_sex_evidence_patrons
                        limit = {
                            is_alive = yes
                            NOT = { this = scope:domcom_integrity_subject }
                            scope:domcom_integrity_subject = { NOT = { has_variable = domcom_cuck_origin_patron } }
                        }
                        save_temporary_scope_as = domcom_integrity_candidate
                        scope:domcom_integrity_subject = {
                            set_variable = { name = domcom_cuck_origin_patron value = scope:domcom_integrity_candidate }
                        }
                    }
                }

                # Definite false-paternity evidence: a publicly attributed child whose stored real father
                # is somebody other than the victim.
                if = {
                    limit = { NOT = { has_variable = domcom_cuck_origin_patron } }
                    every_spouse = {
                        save_temporary_scope_as = domcom_integrity_parent_partner
                        every_child = {
                            limit = {
                                father ?= scope:domcom_integrity_subject
                                exists = real_father
                                real_father = { NOT = { is_consort_of = scope:domcom_integrity_parent_partner } }
                                NOT = { real_father ?= scope:domcom_integrity_subject }
                                scope:domcom_integrity_subject = { NOT = { has_variable = domcom_cuck_origin_patron } }
                            }
                            real_father = { save_temporary_scope_as = domcom_integrity_candidate }
                            scope:domcom_integrity_subject = {
                                set_variable = { name = domcom_cuck_origin_patron value = scope:domcom_integrity_candidate }
                            }
                        }
                    }
                }

                # Current spouse Lover/Soulmate is usable surviving evidence for legacy saves, but only
                # if nothing stronger established origin.
                if = {
                    limit = { NOT = { has_variable = domcom_cuck_origin_patron } }
                    every_spouse = {
                        save_temporary_scope_as = domcom_integrity_current_partner
                        every_relation = {
                            type = lover
                            type = soulmate
                            limit = {
                                is_alive = yes
                                NOT = { this = scope:domcom_integrity_subject }
                                NOT = { is_consort_of = scope:domcom_integrity_current_partner }
                                scope:domcom_integrity_subject = { NOT = { has_variable = domcom_cuck_origin_patron } }
                            }
                            save_temporary_scope_as = domcom_integrity_candidate
                            scope:domcom_integrity_subject = {
                                set_variable = { name = domcom_cuck_origin_patron value = scope:domcom_integrity_candidate }
                            }
                        }
                    }
                }

                # A non-self historical Patron is better than inventing one.
                if = {
                    limit = {
                        NOT = { has_variable = domcom_cuck_origin_patron }
                        has_variable_list = domcom_cuck_patrons
                    }
                    every_in_list = {
                        variable = domcom_cuck_patrons
                        limit = {
                            is_alive = yes
                            NOT = { this = scope:domcom_integrity_subject }
                            scope:domcom_integrity_subject = { NOT = { has_variable = domcom_cuck_origin_patron } }
                        }
                        save_temporary_scope_as = domcom_integrity_candidate
                        scope:domcom_integrity_subject = {
                            set_variable = { name = domcom_cuck_origin_patron value = scope:domcom_integrity_candidate }
                        }
                    }
                }

                # Last-resort current pointers. These are deliberately after real evidence because old
                # versions sometimes repurposed them.
                if = {
                    limit = {
                        NOT = { has_variable = domcom_cuck_origin_patron }
                        has_variable = domcom_cuck_registry_patron
                        NOT = { var:domcom_cuck_registry_patron = scope:domcom_integrity_subject }
                    }
                    set_variable = { name = domcom_cuck_origin_patron value = var:domcom_cuck_registry_patron }
                }
                if = {
                    limit = {
                        NOT = { has_variable = domcom_cuck_origin_patron }
                        has_variable = domcom_cuck_patron
                        NOT = { var:domcom_cuck_patron = scope:domcom_integrity_subject }
                    }
                    set_variable = { name = domcom_cuck_origin_patron value = var:domcom_cuck_patron }
                }
                if = {
                    limit = {
                        NOT = { has_variable = domcom_cuck_origin_patron }
                        has_variable = domcom_patron
                        NOT = { var:domcom_patron = scope:domcom_integrity_subject }
                    }
                    set_variable = { name = domcom_cuck_origin_patron value = var:domcom_patron }
                }

                if = {
                    limit = { has_variable = domcom_cuck_origin_patron }
                    var:domcom_cuck_origin_patron = { save_temporary_scope_as = domcom_integrity_origin }
                    if = {
                        limit = {
                            NOT = { scope:domcom_integrity_origin = scope:domcom_integrity_subject }
                            NOT = {
                                any_in_list = {
                                    variable = domcom_cuck_patrons
                                    this = scope:domcom_integrity_origin
                                }
                            }
                        }
                        add_to_variable_list = { name = domcom_cuck_patrons target = scope:domcom_integrity_origin }
                    }
                }
                else = {
                    scope:domcom_integrity_viewer = {
                        add_to_variable_list = { name = domcom_integrity_purge_queue target = scope:domcom_integrity_subject }
                    }
                }
            }
        }

        if = {
            limit = { has_variable_list = domcom_integrity_purge_queue }
            every_in_list = {
                variable = domcom_integrity_purge_queue
                save_temporary_scope_as = domcom_integrity_subject

                # Remove from whichever Patron-local registries still reference it.
                if = {
                    limit = { has_variable = domcom_cuck_registry_patron }
                    var:domcom_cuck_registry_patron = {
                        if = {
                            limit = { has_variable_list = domcom_cucked_registry }
                            remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_integrity_subject }
                        }
                    }
                }
                if = {
                    limit = { has_variable_list = domcom_cuck_patrons }
                    every_in_list = {
                        variable = domcom_cuck_patrons
                        if = {
                            limit = { has_variable_list = domcom_cucked_registry }
                            remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_integrity_subject }
                        }
                    }
                }

                # Legacy 1.2.0 cleanup: purge the permanent household/child opinion records created
                # by an invalid Cucked registration before deleting its relationship pointers. Older repair
                # passes removed the visible trait/modifiers but could leave these -350/-250 opinions behind.
                # Some older saves only kept the singular compromised-partner pointer, so clean that first.
                if = {
                    limit = { has_variable = domcom_compromised_partner }
                    var:domcom_compromised_partner = {
                        save_temporary_scope_as = domcom_integrity_partner
                        scope:domcom_integrity_subject = {
                            remove_opinion = { target = scope:domcom_integrity_partner modifier = domcom_cucked_partner_opinion }
                        }
                        every_child = {
                            save_temporary_scope_as = domcom_integrity_partner_child
                            scope:domcom_integrity_subject = {
                                remove_opinion = { target = scope:domcom_integrity_partner_child modifier = domcom_cucked_child_opinion }
                            }
                        }
                    }
                }
                if = {
                    limit = { has_variable_list = domcom_compromised_partners }
                    every_in_list = {
                        variable = domcom_compromised_partners
                        save_temporary_scope_as = domcom_integrity_partner
                        scope:domcom_integrity_subject = {
                            remove_opinion = { target = scope:domcom_integrity_partner modifier = domcom_cucked_partner_opinion }
                        }
                        every_child = {
                            save_temporary_scope_as = domcom_integrity_partner_child
                            scope:domcom_integrity_subject = {
                                remove_opinion = { target = scope:domcom_integrity_partner_child modifier = domcom_cucked_child_opinion }
                            }
                        }
                    }
                }
                # Catch records from versions predating domcom_compromised_partners and birth-time child
                # opinion entries. Removing a missing opinion modifier is harmless.
                every_spouse = {
                    save_temporary_scope_as = domcom_integrity_spouse
                    scope:domcom_integrity_subject = {
                        remove_opinion = { target = scope:domcom_integrity_spouse modifier = domcom_cucked_partner_opinion }
                    }
                    every_child = {
                        save_temporary_scope_as = domcom_integrity_spouse_child
                        scope:domcom_integrity_subject = {
                            remove_opinion = { target = scope:domcom_integrity_spouse_child modifier = domcom_cucked_child_opinion }
                        }
                    }
                }
                every_child = {
                    save_temporary_scope_as = domcom_integrity_own_child
                    scope:domcom_integrity_subject = {
                        remove_opinion = { target = scope:domcom_integrity_own_child modifier = domcom_cucked_child_opinion }
                    }
                }

                # Remove public Cucked reputation only when Dominion's nickname is the currently
                # displayed nickname; don't erase an unrelated title.
                if = {
                    limit = { has_nickname = nick_domcom_the_cucked }
                    add_character_flag = domcom_cuck_nickname_removed_by_repair
                    remove_nickname = yes
                    domcom_restore_displaced_nickname_after_bad_cuck_effect = yes
                }
                remove_character_flag = domcom_cucked
                remove_character_flag = domcom_cuck_registry_added
                remove_character_flag = domcom_global_cuck_registry_added
                remove_character_modifier = domcom_cucked_modifier
                if = { limit = { has_trait = domcom_cucked_trait } remove_trait = domcom_cucked_trait }
                remove_character_modifier = domcom_humiliated_stage_modifier
                remove_character_modifier = domcom_submissive_stage_modifier
                remove_character_modifier = domcom_broken_stage_modifier
                remove_character_modifier = domcom_abject_stage_modifier
                remove_character_modifier = domcom_final_submission_modifier
                remove_character_modifier = domcom_absolute_devotion_modifier
                remove_character_modifier = domcom_household_final_modifier
                remove_character_flag = domcom_collapse_resolved
                set_variable = { name = domcom_cuck_xp value = 0 }

                remove_variable = domcom_cuck_origin_patron
                remove_variable = domcom_cuck_patron
                remove_variable = domcom_cuck_registry_patron
                remove_variable = domcom_compromised_partner
                clear_variable_list = domcom_compromised_partners
                clear_variable_list = domcom_cuck_patrons
                clear_variable_list = domcom_sex_evidence_patrons
                clear_variable_list = domcom_betrayal_evidence_patrons

                # Children should immediately lose Spawn of a Cuck when no other biological parent still
                # qualifies.
                every_child = {
                    limit = { is_alive = yes }
                    domcom_refresh_spawn_of_cuck_effect = yes
                }

                remove_list_global_variable = {
                    name = domcom_all_cucked
                    target = scope:domcom_integrity_subject
                }
            }
        }
    }

    clear_variable_list = domcom_integrity_purge_queue
}


# 1.10.1 plural-marriage integrity audit. This is deliberately conservative for old saves: an
# attribution to a current lawful co-spouse is removed only when Dominion has no strong actor-specific
# evidence that the cuckoldry genuinely predated or existed independently of the plural marriage.
# Strong evidence means recorded full-sex evidence, an Owned/Patron relationship, or explicit stored
# false-paternity evidence. Ambiguous legacy records are preserved rather than silently rewriting history.
domcom_audit_relationship_integrity_effect = {
    save_scope_as = domcom_audit_viewer
    set_variable = { name = domcom_audit_self_invalid value = 0 }
    set_variable = { name = domcom_audit_cospouse_removed value = 0 }
    set_variable = { name = domcom_audit_cospouse_preserved value = 0 }

    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = { is_alive = yes has_character_flag = domcom_cucked }
            save_temporary_scope_as = domcom_audit_subject

            # Count impossible self-pointers before the established integrity pass removes them.
            if = {
                limit = {
                    OR = {
                        AND = { has_variable = domcom_cuck_origin_patron var:domcom_cuck_origin_patron = scope:domcom_audit_subject }
                        AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_audit_subject }
                        AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_audit_subject }
                    }
                }
                scope:domcom_audit_viewer = { change_variable = { name = domcom_audit_self_invalid add = 1 } }
            }

            remove_character_flag = domcom_audit_origin_is_cospouse
            remove_character_flag = domcom_audit_origin_has_strong_evidence

            if = {
                limit = { has_variable = domcom_cuck_origin_patron }
                var:domcom_cuck_origin_patron = { save_temporary_scope_as = domcom_audit_origin }

                # Does victim and recorded origin currently share at least one lawful spouse/consort?
                every_consort = {
                    save_temporary_scope_as = domcom_audit_possible_shared_partner
                    if = {
                        limit = { scope:domcom_audit_origin = { is_consort_of = scope:domcom_audit_possible_shared_partner } }
                        scope:domcom_audit_subject = { add_character_flag = domcom_audit_origin_is_cospouse }
                    }
                }

                if = {
                    limit = { has_character_flag = domcom_audit_origin_is_cospouse }

                    # Full sex evidence is intentionally treated as strong/ambiguous legacy provenance.
                    # New 1.10.1 hooks no longer create it from lawful co-spouse sex, but an older save may
                    # not contain enough chronology to prove whether the evidence predated the marriage.
                    if = {
                        limit = {
                            has_variable_list = domcom_sex_evidence_patrons
                            any_in_list = { variable = domcom_sex_evidence_patrons this = scope:domcom_audit_origin }
                        }
                        add_character_flag = domcom_audit_origin_has_strong_evidence
                    }
                    if = {
                        limit = {
                            has_character_flag = domcom_owned_cuck
                            has_variable = domcom_patron
                            var:domcom_patron = scope:domcom_audit_origin
                        }
                        add_character_flag = domcom_audit_origin_has_strong_evidence
                    }

                    # Stored false-paternity is strong only when the biological parent is not itself a
                    # lawful spouse/consort of the shared partner.
                    every_spouse = {
                        save_temporary_scope_as = domcom_audit_shared_partner
                        every_child = {
                            limit = {
                                father ?= scope:domcom_audit_subject
                                exists = real_father
                                real_father ?= scope:domcom_audit_origin
                                scope:domcom_audit_origin = { NOT = { is_consort_of = scope:domcom_audit_shared_partner } }
                            }
                            scope:domcom_audit_subject = { add_character_flag = domcom_audit_origin_has_strong_evidence }
                        }
                    }

                    if = {
                        limit = { has_character_flag = domcom_audit_origin_has_strong_evidence }
                        scope:domcom_audit_viewer = { change_variable = { name = domcom_audit_cospouse_preserved add = 1 } }
                    }
                    else = {
                        # Unsupported co-spouse attribution: remove only this actor's provenance. The
                        # established evidence repair below will choose another surviving cucker if one
                        # exists, and purges the public record only when nothing legitimate remains.
                        if = {
                            limit = {
                                has_variable = domcom_cuck_registry_patron
                                var:domcom_cuck_registry_patron = scope:domcom_audit_origin
                            }
                            scope:domcom_audit_origin = {
                                if = {
                                    limit = { has_variable_list = domcom_cucked_registry }
                                    remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_audit_subject }
                                }
                            }
                            remove_variable = domcom_cuck_registry_patron
                        }
                        if = {
                            limit = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_audit_origin }
                            remove_variable = domcom_cuck_patron
                        }
                        if = { limit = { has_variable_list = domcom_cuck_patrons } remove_list_variable = { name = domcom_cuck_patrons target = scope:domcom_audit_origin } }
                        if = { limit = { has_variable_list = domcom_betrayal_evidence_patrons } remove_list_variable = { name = domcom_betrayal_evidence_patrons target = scope:domcom_audit_origin } }
                        remove_variable = domcom_cuck_origin_patron
                        scope:domcom_audit_viewer = { change_variable = { name = domcom_audit_cospouse_removed add = 1 } }
                    }
                }
            }

            remove_character_flag = domcom_audit_origin_is_cospouse
            remove_character_flag = domcom_audit_origin_has_strong_evidence
        }
    }

    # Re-run the established evidence-based integrity pass. It now ignores current lawful co-spouse
    # Lover/Soulmate and lawful-co-spouse paternity as reconstruction sources.
    remove_character_flag = domcom_cuck_integrity_repaired_096
    domcom_repair_cuck_integrity_096_effect = yes
}

domcom_migrate_cospouse_integrity_1101_once_effect = {
    if = {
        limit = { is_ai = no NOT = { has_character_flag = domcom_cospouse_integrity_migrated_1101 } }
        domcom_audit_relationship_integrity_effect = yes
        add_character_flag = domcom_cospouse_integrity_migrated_1101
        if = {
            limit = {
                OR = {
                    var:domcom_audit_self_invalid > 0
                    var:domcom_audit_cospouse_removed > 0
                }
            }
            send_interface_toast = {
                type = event_toast_effect_good
                title = DOMCOM_AUDIT_MIGRATION_TOAST
                left_icon = root
            }
        }
    }
}

# 1.2.0 migration wrapper. The old _096 pass was one-shot; existing saves that had already run it
# would otherwise never receive later cleanup improvements. Clear the old marker exactly once and rerun
# the evidence-based repair, then mark this migration complete.
domcom_repair_cuck_integrity_120_effect = {
    if = {
        limit = {
            is_ai = no
            NOT = { has_character_flag = domcom_cuck_integrity_repaired_120 }
        }
        remove_character_flag = domcom_cuck_integrity_repaired_096
        domcom_repair_cuck_integrity_096_effect = yes
        add_character_flag = domcom_cuck_integrity_repaired_120
    }
}

domcom_repair_patron_registries_effect = {
    domcom_repair_cuck_integrity_120_effect = yes
    domcom_migrate_cospouse_integrity_1101_once_effect = yes
    save_scope_as = domcom_registry_patron

    if = {
        limit = {
            is_ai = no
            NOT = { has_character_flag = domcom_registry_bootstrap_092 }
        }
        add_character_flag = domcom_registry_bootstrap_092

        if = {
            limit = { has_global_variable_list = domcom_all_cucked }
            every_in_global_list = {
                variable = domcom_all_cucked
                limit = { is_alive = yes has_character_flag = domcom_cucked }
                save_temporary_scope_as = domcom_registry_subject

                if = {
                    limit = { NOT = { has_variable = domcom_cuck_origin_patron } }
                    if = {
                        limit = {
                            has_variable = domcom_cuck_registry_patron
                            NOT = { var:domcom_cuck_registry_patron = scope:domcom_registry_subject }
                        }
                        set_variable = { name = domcom_cuck_origin_patron value = var:domcom_cuck_registry_patron }
                    }
                    else_if = {
                        limit = {
                            has_variable = domcom_cuck_patron
                            NOT = { var:domcom_cuck_patron = scope:domcom_registry_subject }
                        }
                        set_variable = { name = domcom_cuck_origin_patron value = var:domcom_cuck_patron }
                    }
                    else_if = {
                        limit = {
                            has_variable = domcom_patron
                            NOT = { var:domcom_patron = scope:domcom_registry_subject }
                        }
                        set_variable = { name = domcom_cuck_origin_patron value = var:domcom_patron }
                    }
                }
                if = {
                    limit = {
                        has_variable = domcom_cuck_origin_patron
                        NOT = { has_variable_list = domcom_cuck_patrons }
                    }
                    var:domcom_cuck_origin_patron = { save_scope_as = domcom_registry_origin }
                    add_to_variable_list = { name = domcom_cuck_patrons target = scope:domcom_registry_origin }
                }

                # Recover current ownership for the human Patron without trusting the dynasty list that
                # may have gone stale in an older version.
                if = {
                    limit = {
                        has_character_flag = domcom_owned_cuck
                        has_variable = domcom_patron
                        var:domcom_patron = scope:domcom_registry_patron
                    }
                    scope:domcom_registry_patron = {
                        if = {
                            limit = {
                                NOT = {
                                    any_in_list = {
                                        variable = domcom_owned_registry
                                        this = scope:domcom_registry_subject
                                    }
                                }
                            }
                            add_to_variable_list = { name = domcom_owned_registry target = scope:domcom_registry_subject }
                        }
                    }
                    if = {
                        limit = { exists = scope:domcom_registry_patron.dynasty }
                        scope:domcom_registry_patron.dynasty = {
                            if = {
                                limit = {
                                    NOT = {
                                        any_in_list = {
                                            variable = domcom_owned_subjects
                                            this = scope:domcom_registry_subject
                                        }
                                    }
                                }
                                add_to_variable_list = { name = domcom_owned_subjects target = scope:domcom_registry_subject }
                            }
                        }
                    }
                }
            }
        }
    }

    # Recover exact-source Dynastic Prospects from each Owned character's own admirer list. This repairs
    # both the Ledger page and background approaches.
    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_registry_patron
                has_variable_list = domcom_family_admirers
            }
            save_temporary_scope_as = domcom_registry_source
            every_in_list = {
                variable = domcom_family_admirers
                limit = {
                    is_alive = yes age >= 18
                    has_variable = domcom_crush_patron
                    var:domcom_crush_patron = scope:domcom_registry_patron
                    has_variable = domcom_crush_source
                    var:domcom_crush_source = scope:domcom_registry_source
                    OR = {
                        has_relation_crush = scope:domcom_registry_patron
                        has_relation_lover = scope:domcom_registry_patron
                        has_relation_soulmate = scope:domcom_registry_patron
                    }
                }
                save_temporary_scope_as = domcom_registry_admirer
                scope:domcom_registry_patron = {
                    if = {
                        limit = {
                            NOT = {
                                any_in_list = {
                                    variable = domcom_crush_candidates
                                    this = scope:domcom_registry_admirer
                                }
                            }
                        }
                        add_to_variable_list = { name = domcom_crush_candidates target = scope:domcom_registry_admirer }
                    }
                }
            }
        }
    }
}

# Run from the Patron. Uses Patron-local and dynasty registries, so normal monthly upkeep does not scan
# the world. This is also the backend for Enforce Dominion.
domcom_enforce_communion_for_patron_effect = {
    domcom_repair_patron_registries_effect = yes
    save_scope_as = domcom_communion_patron

    domcom_repair_communion_intimates_effect = yes

    # When the Ledger is open, its collected roster is the most authoritative repair list for an existing
    # save and avoids depending on old registry data.
    if = {
        limit = { has_variable_list = domcom_ui_owned_raw }
        every_in_list = {
            variable = domcom_ui_owned_raw
            limit = {
                is_alive = yes
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_communion_patron
            }
            domcom_apply_communion_tolerance_subject_effect = yes
        }
    }

    # Normal automatic upkeep prefers the Patron-local registry repaired above. The dynasty list remains
    # a fallback for saves that have not yet bootstrapped.
    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_communion_patron
            }
            domcom_apply_communion_tolerance_subject_effect = yes
        }
    }
    else_if = {
        limit = { exists = dynasty dynasty = { has_variable_list = domcom_owned_subjects } }
        dynasty = {
            every_in_list = {
                variable = domcom_owned_subjects
                limit = {
                    is_alive = yes
                    has_variable = domcom_patron
                    var:domcom_patron = scope:domcom_communion_patron
                }
                domcom_apply_communion_tolerance_subject_effect = yes
            }
        }
    }
}

domcom_fast_recover_records_effect = {
    save_scope_as = domcom_ui_patron
    save_scope_as = domcom_owner

    # Current lovers/soulmates: their other spouses are recoverable cucks.
    every_relation = {
        type = lover
        type = soulmate
        limit = {
            is_alive = yes age >= 18 is_married = yes
            NOT = { is_consort_of = scope:domcom_ui_patron }
        }
        every_spouse = {
            limit = {
                is_alive = yes age >= 18
                NOT = { this = scope:domcom_ui_patron }
                OR = { NOT = { has_variable = domcom_cuck_patron } var:domcom_cuck_patron = scope:domcom_ui_patron }
                domcom_has_qualifying_cuck_evidence_from_patron_trigger = { PATRON = scope:domcom_ui_patron }
            }
            domcom_register_cuck_generic_effect = yes
        }
    }

    # Child evidence catches households even when the lover relationship is gone.
    every_child = {
        if = {
            limit = { father ?= scope:domcom_ui_patron exists = mother }
            mother = {
                if = {
                    limit = { NOT = { is_consort_of = scope:domcom_ui_patron } }
                    every_spouse = {
                    limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_ui_patron } }
                        domcom_register_cuck_generic_effect = yes
                    }
                }
            }
        }
        else_if = {
            limit = { real_father ?= scope:domcom_ui_patron exists = mother }
            mother = {
                if = {
                    limit = { NOT = { is_consort_of = scope:domcom_ui_patron } }
                    every_spouse = {
                        limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_ui_patron } }
                        domcom_register_cuck_generic_effect = yes
                    }
                }
            }
        }
        else_if = {
            limit = { mother ?= scope:domcom_ui_patron exists = father }
            father = {
                if = {
                    limit = { NOT = { is_consort_of = scope:domcom_ui_patron } }
                    every_spouse = {
                        limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_ui_patron } }
                        domcom_register_cuck_generic_effect = yes
                    }
                }
            }
        }
    }
}

# COMMUNION LEDGER / GUI SUPPORT

domcom_prepare_cucked_link_effect = {
    remove_variable = domcom_ui_compromised_partner
    remove_variable = domcom_ui_compromised_link_type

    if = {
        limit = { any_spouse = { is_alive = yes has_relation_soulmate = scope:domcom_ui_patron } }
        random_spouse = {
            limit = { is_alive = yes has_relation_soulmate = scope:domcom_ui_patron }
            save_temporary_scope_as = domcom_ui_link_partner
        }
        set_variable = { name = domcom_ui_compromised_partner value = scope:domcom_ui_link_partner }
        set_variable = { name = domcom_ui_compromised_link_type value = flag:soulmate }
        set_variable = { name = domcom_compromised_partner value = scope:domcom_ui_link_partner }
    }
    else_if = {
        limit = { any_spouse = { is_alive = yes has_relation_lover = scope:domcom_ui_patron } }
        random_spouse = {
            limit = { is_alive = yes has_relation_lover = scope:domcom_ui_patron }
            save_temporary_scope_as = domcom_ui_link_partner
        }
        set_variable = { name = domcom_ui_compromised_partner value = scope:domcom_ui_link_partner }
        set_variable = { name = domcom_ui_compromised_link_type value = flag:lover }
        set_variable = { name = domcom_compromised_partner value = scope:domcom_ui_link_partner }
    }
    else_if = {
        limit = {
            any_spouse = {
                is_alive = yes
                has_character_flag = domcom_communion_intimate_bound
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_ui_patron
            }
        }
        random_spouse = {
            limit = {
                is_alive = yes
                has_character_flag = domcom_communion_intimate_bound
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_ui_patron
            }
            save_temporary_scope_as = domcom_ui_link_partner
        }
        set_variable = { name = domcom_ui_compromised_partner value = scope:domcom_ui_link_partner }
        set_variable = { name = domcom_ui_compromised_link_type value = flag:bound }
        set_variable = { name = domcom_compromised_partner value = scope:domcom_ui_link_partner }
    }
    else_if = {
        limit = {
            any_spouse = {
                is_alive = yes
                any_child = {
                    OR = {
                        father ?= scope:domcom_ui_patron
                        mother ?= scope:domcom_ui_patron
                        real_father ?= scope:domcom_ui_patron
                    }
                }
            }
        }
        random_spouse = {
            limit = {
                is_alive = yes
                any_child = {
                    OR = {
                        father ?= scope:domcom_ui_patron
                        mother ?= scope:domcom_ui_patron
                        real_father ?= scope:domcom_ui_patron
                    }
                }
            }
            save_temporary_scope_as = domcom_ui_link_partner
        }
        set_variable = { name = domcom_ui_compromised_partner value = scope:domcom_ui_link_partner }
        set_variable = { name = domcom_ui_compromised_link_type value = flag:blood }
        set_variable = { name = domcom_compromised_partner value = scope:domcom_ui_link_partner }
    }
    else_if = {
        limit = {
            has_variable = domcom_compromised_partner
            var:domcom_compromised_partner = { is_alive = yes }
        }
        set_variable = { name = domcom_ui_compromised_partner value = var:domcom_compromised_partner }
        set_variable = { name = domcom_ui_compromised_link_type value = flag:historical }
    }
}

# Clear raw/display roster caches so ordinary navigation keeps only one population-heavy page in memory.
domcom_clear_ui_raw_roster_caches_effect = {
    clear_variable_list = domcom_ui_cucked_raw
    clear_variable_list = domcom_ui_world_cucks_raw
    clear_variable_list = domcom_ui_owned_raw
    clear_variable_list = domcom_ui_endowments_raw
    clear_variable_list = domcom_ui_lovers_raw
    clear_variable_list = domcom_ui_lovers
    clear_variable_list = domcom_ui_prospects_raw
    clear_variable_list = domcom_ui_blood_raw
    clear_variable_list = domcom_ui_tantalized_raw
    clear_variable_list = domcom_ui_lick_raw
    clear_variable_list = domcom_ui_lick_subjects
    clear_variable_list = domcom_lick_page_list
    clear_variable_list = domcom_ui_cucked_subjects
    clear_variable_list = domcom_ui_world_cucks
    clear_variable_list = domcom_ui_owned_subjects
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_prospects
    clear_variable_list = domcom_ui_blood_children
    clear_variable_list = domcom_ui_tantalized
    domcom_clear_standard_ui_page_caches_effect = yes
}

# Lightweight persistent summary for the Overview page. This counts authoritative registries and
# current intimate relations without constructing any portrait/display roster, so Overview is accurate
# immediately when Communion opens while retaining the lazy-page crash protection.
domcom_refresh_overview_summary_effect = {
    save_scope_as = domcom_ui_summary_patron

    set_variable = { name = domcom_ui_cucked_count value = 0 }
    set_variable = { name = domcom_ui_world_cuck_count value = 0 }
    set_variable = { name = domcom_ui_owned_count value = 0 }
    set_variable = { name = domcom_ui_lovers_count value = 0 }
    set_variable = { name = domcom_ui_prospect_count value = 0 }
    set_variable = { name = domcom_ui_blood_count value = 0 }
    set_variable = { name = domcom_ui_tantalized_count value = 0 }
    set_variable = { name = domcom_ui_tantalized_women value = 0 }
    set_variable = { name = domcom_ui_tantalized_men value = 0 }
    set_variable = { name = domcom_ui_pet_count value = 0 }
    set_variable = { name = domcom_ui_royal_owned_count value = 0 }
    set_variable = { name = domcom_ui_household_count value = 0 }

    if = {
        limit = { has_variable_list = domcom_cucked_registry }
        every_in_list = {
            variable = domcom_cucked_registry
            limit = {
                is_alive = yes age >= 18 has_character_flag = domcom_cucked
                OR = {
                    any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_ui_summary_patron }
                    AND = {
                        NOT = { has_variable_list = domcom_cuck_patrons }
                        has_variable = domcom_cuck_origin_patron
                        var:domcom_cuck_origin_patron = scope:domcom_ui_summary_patron
                    }
                }
            }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_cucked_count add = 1 } }
        }
    }

    # World Cucks is global by definition, but this pass only counts entries. It never creates GUI rows.
    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = {
                is_alive = yes age >= 18 has_character_flag = domcom_cucked
                NOT = {
                    OR = {
                        any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_ui_summary_patron }
                        AND = {
                            NOT = { has_variable_list = domcom_cuck_patrons }
                            has_variable = domcom_cuck_origin_patron
                            var:domcom_cuck_origin_patron = scope:domcom_ui_summary_patron
                        }
                    }
                }
            }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_world_cuck_count add = 1 } }
        }
    }

    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = {
                is_alive = yes has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron var:domcom_patron = scope:domcom_ui_summary_patron
            }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_owned_count add = 1 } }
            if = { limit = { highest_held_title_tier >= tier_kingdom } scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_royal_owned_count add = 1 } } }
            if = { limit = { has_character_flag = domcom_household_dominion } scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_household_count add = 1 } } }
        }
    }

    # Intimate bonds use a tiny temporary de-duplication list because Lover and Soulmate relations can
    # overlap the Dominion-protected intimate registry. The list is destroyed before this effect returns.
    clear_variable_list = domcom_ui_summary_lovers_seen
    every_relation = {
        type = lover
        type = soulmate
        limit = { is_alive = yes NOT = { this = scope:domcom_ui_summary_patron } }
        save_temporary_scope_as = domcom_ui_summary_lover
        scope:domcom_ui_summary_patron = {
            if = {
                limit = { NOT = { any_in_list = { variable = domcom_ui_summary_lovers_seen this = scope:domcom_ui_summary_lover } } }
                add_to_variable_list = { name = domcom_ui_summary_lovers_seen target = scope:domcom_ui_summary_lover }
                change_variable = { name = domcom_ui_lovers_count add = 1 }
            }
        }
    }
    if = {
        limit = { has_variable_list = domcom_intimate_registry }
        every_in_list = {
            variable = domcom_intimate_registry
            limit = {
                is_alive = yes has_character_flag = domcom_communion_intimate_bound
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_ui_summary_patron
            }
            save_temporary_scope_as = domcom_ui_summary_lover
            scope:domcom_ui_summary_patron = {
                if = {
                    limit = { NOT = { any_in_list = { variable = domcom_ui_summary_lovers_seen this = scope:domcom_ui_summary_lover } } }
                    add_to_variable_list = { name = domcom_ui_summary_lovers_seen target = scope:domcom_ui_summary_lover }
                    change_variable = { name = domcom_ui_lovers_count add = 1 }
                }
            }
        }
    }
    clear_variable_list = domcom_ui_summary_lovers_seen

    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        every_in_list = {
            variable = domcom_crush_candidates
            limit = { is_alive = yes age >= 18 has_variable = domcom_crush_patron var:domcom_crush_patron = scope:domcom_ui_summary_patron }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_prospect_count add = 1 } }
        }
    }

    if = {
        limit = { has_variable_list = domcom_blood_registry }
        every_in_list = {
            variable = domcom_blood_registry
            limit = { is_alive = yes domcom_is_unacknowledged_blood_trigger = yes }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_blood_count add = 1 } }
        }
    }

    if = {
        limit = { has_variable_list = domcom_tantalized_registry }
        every_in_list = {
            variable = domcom_tantalized_registry
            limit = { is_alive = yes has_variable = domcom_obedience_patron var:domcom_obedience_patron = scope:domcom_ui_summary_patron }
            scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_tantalized_count add = 1 } }
            if = { limit = { is_female = yes } scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_tantalized_women add = 1 } } }
            else_if = { limit = { is_male = yes } scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_tantalized_men add = 1 } } }
            if = { limit = { has_character_flag = domcom_pet } scope:domcom_ui_summary_patron = { change_variable = { name = domcom_ui_pet_count add = 1 } } }
        }
    }
}

# After an action mutates Dominion state, rebuild only the page the player is currently viewing. This
# prevents Refresh/Audit/Enforce/etc. from selecting a page whose backing list was just erased.
domcom_refresh_current_ui_page_effect = {
    domcom_refresh_overview_summary_effect = yes

    if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:cucked }
        domcom_prepare_cucked_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:world_cucks }
        domcom_clear_ui_raw_roster_caches_effect = yes
        domcom_prepare_world_cucks_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:owned }
        domcom_prepare_owned_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:endowments }
        domcom_prepare_endowments_roster_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:lovers }
        domcom_clear_ui_raw_roster_caches_effect = yes
        domcom_prepare_lovers_roster_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:prospects }
        domcom_prepare_prospects_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:blood }
        domcom_prepare_blood_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:tantalized }
        domcom_prepare_tantalized_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:secrets }
        domcom_prepare_owned_page_safe_effect = yes
    }
    else_if = {
        limit = { exists = var:domcom_ui_page var:domcom_ui_page = flag:imperial }
        domcom_prepare_lick_page_safe_effect = yes
    }
}

# 2.0 crash safety: opening Communion must never run the historical world repair/roster pass.
# This only creates a predictable empty UI shell. Individual pages populate their own bounded data
# when the player explicitly asks for them.
domcom_prepare_ui_shell_effect = {
    domcom_initialize_ledger_counters_effect = yes
    domcom_clear_ui_raw_roster_caches_effect = yes
    clear_variable_list = domcom_lick_subjects
    clear_variable_list = domcom_lick_page_list
    domcom_refresh_overview_summary_effect = yes
    set_variable = { name = domcom_ui_filtered_cucked_count value = 0 }
    set_variable = { name = domcom_ui_filtered_owned_count value = 0 }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_mode } } set_variable = { name = domcom_ui_sort_mode value = flag:rank } }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_direction } } set_variable = { name = domcom_ui_sort_direction value = flag:descending } }
    if = { limit = { NOT = { exists = var:domcom_ui_filter_mode } } set_variable = { name = domcom_ui_filter_mode value = flag:all } }
    save_scope_as = domcom_ui_patron
    save_scope_as = domcom_owner
}

# Lightweight page collectors deliberately avoid the old repair/migration/profile-refresh pass.
domcom_prepare_cucked_page_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    save_scope_as = domcom_owner
    # Bounded retroactive discovery: current lovers/soulmates and direct child evidence only. This is
    # intentionally safe for the lazy Ledger and does not scan every living character.
    domcom_fast_recover_records_effect = yes
    clear_variable_list = domcom_ui_cucked_raw
    set_variable = { name = domcom_ui_cucked_count value = 0 }

    # Patron-local registry is the fastest authoritative source for the personal Cucked page. Repair its
    # global membership while collecting so a lost World registry entry heals immediately.
    if = {
        limit = { has_variable_list = domcom_cucked_registry }
        every_in_list = {
            variable = domcom_cucked_registry
            limit = {
                is_alive = yes age >= 18 has_character_flag = domcom_cucked
                OR = {
                    any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_ui_patron }
                    AND = { NOT = { has_variable_list = domcom_cuck_patrons } has_variable = domcom_cuck_origin_patron var:domcom_cuck_origin_patron = scope:domcom_ui_patron }
                    AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_ui_patron }
                }
            }
            save_temporary_scope_as = domcom_ui_ref
            domcom_refresh_cuck_reputation_effect = yes
            scope:domcom_ui_patron = {
                if = {
                    limit = { NOT = { any_in_list = { variable = domcom_ui_cucked_raw this = scope:domcom_ui_ref } } }
                    add_to_variable_list = { name = domcom_ui_cucked_raw target = scope:domcom_ui_ref }
                    change_variable = { name = domcom_ui_cucked_count add = 1 }
                }
            }
        }
    }

    # Merge any valid historical records found only in the global registry without duplicating local ones.
    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = {
                is_alive = yes age >= 18 has_character_flag = domcom_cucked
                OR = {
                    any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_ui_patron }
                    AND = { NOT = { has_variable_list = domcom_cuck_patrons } has_variable = domcom_cuck_origin_patron var:domcom_cuck_origin_patron = scope:domcom_ui_patron }
                    AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_ui_patron }
                }
            }
            save_temporary_scope_as = domcom_ui_ref
            scope:domcom_ui_patron = {
                if = {
                    limit = { NOT = { any_in_list = { variable = domcom_ui_cucked_raw this = scope:domcom_ui_ref } } }
                    add_to_variable_list = { name = domcom_ui_cucked_raw target = scope:domcom_ui_ref }
                    change_variable = { name = domcom_ui_cucked_count add = 1 }
                }
            }
        }
    }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_owned_page_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_owned_raw
    set_variable = { name = domcom_ui_owned_count value = 0 }
    set_variable = { name = domcom_ui_royal_owned_count value = 0 }
    set_variable = { name = domcom_ui_household_count value = 0 }
    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = { is_alive = yes has_character_flag = domcom_owned_cuck has_variable = domcom_patron var:domcom_patron = scope:domcom_ui_patron }
            save_temporary_scope_as = domcom_ui_ref
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_owned_raw target = scope:domcom_ui_ref }
                change_variable = { name = domcom_ui_owned_count add = 1 }
            }
            if = { limit = { highest_held_title_tier >= tier_kingdom } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_royal_owned_count add = 1 } } }
            if = { limit = { has_character_flag = domcom_household_dominion } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_household_count add = 1 } } }
        }
    }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_prospects_page_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_prospects_raw
    set_variable = { name = domcom_ui_prospect_count value = 0 }
    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        every_in_list = {
            variable = domcom_crush_candidates
            limit = { is_alive = yes age >= 18 has_variable = domcom_crush_patron var:domcom_crush_patron = scope:domcom_ui_patron }
            save_temporary_scope_as = domcom_ui_ref
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_prospects_raw target = scope:domcom_ui_ref }
                change_variable = { name = domcom_ui_prospect_count add = 1 }
            }
        }
    }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_blood_page_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_blood_raw
    set_variable = { name = domcom_ui_blood_count value = 0 }
    if = {
        limit = { has_variable_list = domcom_blood_registry }
        every_in_list = {
            variable = domcom_blood_registry
            limit = { is_alive = yes domcom_is_unacknowledged_blood_trigger = yes }
            save_temporary_scope_as = domcom_ui_ref
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_ref }
                change_variable = { name = domcom_ui_blood_count add = 1 }
            }
        }
    }

    # 2.6.56 — keep disputed direct parentage visible on every Blood-page refresh, not only when the
    # whole Ledger is rebuilt. This is deliberately bounded to the player's own children.
    every_child = {
        limit = {
            is_alive = yes
            exists = father
            exists = real_father
            NOT = { father = real_father }
            OR = {
                father = scope:domcom_ui_patron
                mother = scope:domcom_ui_patron
                real_father = scope:domcom_ui_patron
            }
        }
        save_temporary_scope_as = domcom_ui_parentage_child
        if = {
            limit = {
                scope:domcom_ui_patron = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_ui_blood_raw
                            this = scope:domcom_ui_parentage_child
                        }
                    }
                }
            }
            domcom_initialize_profile_effect = yes
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_parentage_child }
                change_variable = { name = domcom_ui_blood_count add = 1 }
            }
        }
    }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_tantalized_page_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_tantalized_raw
    set_variable = { name = domcom_ui_tantalized_count value = 0 }
    set_variable = { name = domcom_ui_tantalized_women value = 0 }
    set_variable = { name = domcom_ui_tantalized_men value = 0 }
    set_variable = { name = domcom_ui_pet_count value = 0 }
    if = {
        limit = { has_variable_list = domcom_tantalized_registry }
        every_in_list = {
            variable = domcom_tantalized_registry
            limit = { is_alive = yes has_variable = domcom_obedience_patron var:domcom_obedience_patron = scope:domcom_ui_patron }
            save_temporary_scope_as = domcom_ui_ref
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_tantalized_raw target = scope:domcom_ui_ref }
                change_variable = { name = domcom_ui_tantalized_count add = 1 }
            }
            if = { limit = { is_female = yes } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_tantalized_women add = 1 } } }
            else_if = { limit = { is_male = yes } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_tantalized_men add = 1 } } }
            if = { limit = { has_character_flag = domcom_pet } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_pet_count add = 1 } } }
        }
    }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_ui_effect = {
    domcom_initialize_ledger_counters_effect = yes
    clear_variable_list = domcom_ui_cucked_raw
    clear_variable_list = domcom_ui_world_cucks_raw
    clear_variable_list = domcom_ui_owned_raw
    clear_variable_list = domcom_ui_lovers_raw
    clear_variable_list = domcom_ui_lovers
    clear_variable_list = domcom_ui_prospects_raw
    clear_variable_list = domcom_ui_blood_raw
    clear_variable_list = domcom_ui_tantalized_raw
    clear_variable_list = domcom_ui_cucked_subjects
    clear_variable_list = domcom_ui_world_cucks
    clear_variable_list = domcom_ui_owned_subjects
    clear_variable_list = domcom_ui_prospects
    clear_variable_list = domcom_ui_blood_children
    clear_variable_list = domcom_ui_tantalized
    clear_variable_list = domcom_ui_cucked_page_list
    clear_variable_list = domcom_ui_owned_page_list
    clear_variable_list = domcom_ui_endowments_page_list
    clear_variable_list = domcom_ui_outcomes_page_list
    clear_variable_list = domcom_ui_lovers_page_list
    clear_variable_list = domcom_ui_prospects_page_list
    clear_variable_list = domcom_ui_blood_page_list
    clear_variable_list = domcom_ui_tantalized_page_list
    clear_variable_list = domcom_ui_secrets_page_list
    clear_variable_list = domcom_lick_page_list
    clear_variable_list = domcom_lick_subjects
    set_variable = { name = domcom_ui_cucked_count value = 0 }
    set_variable = { name = domcom_ui_world_cuck_count value = 0 }
    set_variable = { name = domcom_ui_owned_count value = 0 }
    set_variable = { name = domcom_ui_lovers_count value = 0 }
    set_variable = { name = domcom_ui_prospect_count value = 0 }
    set_variable = { name = domcom_ui_blood_count value = 0 }
    set_variable = { name = domcom_ui_royal_owned_count value = 0 }
    set_variable = { name = domcom_ui_household_count value = 0 }
    set_variable = { name = domcom_ui_filtered_cucked_count value = 0 }
    set_variable = { name = domcom_ui_filtered_owned_count value = 0 }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_mode } } set_variable = { name = domcom_ui_sort_mode value = flag:rank } }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_direction } } set_variable = { name = domcom_ui_sort_direction value = flag:descending } }
    if = { limit = { NOT = { exists = var:domcom_ui_filter_mode } } set_variable = { name = domcom_ui_filter_mode value = flag:all } }
    save_scope_as = domcom_ui_patron
    save_scope_as = domcom_owner

    domcom_initialize_local_population_effect = yes
    domcom_fast_recover_records_effect = yes
    domcom_repair_patron_registries_effect = yes
    domcom_repair_pet_registry_for_patron_effect = yes
    if = { limit = { is_ai = no } domcom_refresh_owned_benefit_tier_effect = yes }

    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = { is_alive = yes age >= 18 has_character_flag = domcom_cucked }
            save_temporary_scope_as = domcom_ui_roster_subject

            if = {
                limit = {
                    OR = {
                        any_in_list = {
                            variable = domcom_cuck_patrons
                            this = scope:domcom_ui_patron
                        }
                        AND = {
                            NOT = { has_variable_list = domcom_cuck_patrons }
                            has_variable = domcom_cuck_origin_patron
                            var:domcom_cuck_origin_patron = scope:domcom_ui_patron
                        }
                    }
                }
                domcom_initialize_profile_effect = yes
                domcom_refresh_cuck_stage_effect = yes
                domcom_refresh_cuck_reputation_effect = yes
                set_variable = { name = domcom_ui_alpha_chance value = domcom_ui_alpha_check_chance_value }
                domcom_prepare_cucked_link_effect = yes
                scope:domcom_ui_patron = {
                    add_to_variable_list = { name = domcom_ui_cucked_raw target = scope:domcom_ui_roster_subject }
                    change_variable = { name = domcom_ui_cucked_count add = 1 }
                }
            }
            else = {
                # Preserve the exact old definition of World Cucks: living Cucked characters outside this
                # Patron's personal Cucked history.
                scope:domcom_ui_patron = {
                    change_variable = { name = domcom_ui_world_cuck_count add = 1 }
                }
            }
        }
    }

    # Owned roster uses the repaired Patron-local registry. Dynasty storage is still maintained for
    # inheritance but is no longer a single point of failure.
    if = {
        limit = { has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = { is_alive = yes has_character_flag = domcom_owned_cuck has_variable = domcom_patron var:domcom_patron = scope:domcom_ui_patron }
            domcom_initialize_profile_effect = yes
            domcom_refresh_cuck_reputation_effect = yes
            save_temporary_scope_as = domcom_ui_owned_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_owned_raw target = scope:domcom_ui_owned_subject }
                change_variable = { name = domcom_ui_owned_count add = 1 }
            }
            if = { limit = { highest_held_title_tier >= tier_kingdom } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_royal_owned_count add = 1 } } }
            if = { limit = { has_character_flag = domcom_household_dominion } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_household_count add = 1 } } }
        }
    }

    # Current Lovers/Soulmates are a tiny relationship graph compared with world rosters, so the
    # dedicated Lovers page can always be prepared cheaply.
    domcom_prepare_lovers_roster_effect = yes

    # Prospects were already stored on the patron at creation; no world scan needed.
    if = {
        limit = { has_variable_list = domcom_crush_candidates }
        every_in_list = {
            variable = domcom_crush_candidates
            limit = {
                is_alive = yes age >= 18
                has_variable = domcom_crush_patron var:domcom_crush_patron = scope:domcom_ui_patron
                OR = { has_relation_crush = scope:domcom_ui_patron has_relation_lover = scope:domcom_ui_patron has_relation_soulmate = scope:domcom_ui_patron }
            }
            domcom_initialize_profile_effect = yes
            save_temporary_scope_as = domcom_ui_prospect
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_prospects_raw target = scope:domcom_ui_prospect }
                change_variable = { name = domcom_ui_prospect_count add = 1 }
            }
        }
    }

    if = {
        limit = { has_variable_list = domcom_blood_registry }
        every_in_list = {
            variable = domcom_blood_registry
            limit = { is_alive = yes domcom_is_unacknowledged_blood_trigger = yes }
            domcom_initialize_profile_effect = yes
            save_temporary_scope_as = domcom_ui_blood_child
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_blood_child }
                change_variable = { name = domcom_ui_blood_count add = 1 }
            }
        }
    }

    # 2.6.56 — Parentage desk: include direct children for whom CK3 already stores a different
    # public father and real_father. This lets an assumed father, mother, or biological father act
    # from a visible Ledger row instead of hunting through secrets or modifiers.
    every_child = {
        limit = {
            is_alive = yes
            exists = father
            exists = real_father
            NOT = { father = real_father }
            OR = {
                father = scope:domcom_ui_patron
                mother = scope:domcom_ui_patron
                real_father = scope:domcom_ui_patron
            }
        }
        save_temporary_scope_as = domcom_ui_parentage_child
        if = {
            limit = {
                scope:domcom_ui_patron = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_ui_blood_raw
                            this = scope:domcom_ui_parentage_child
                        }
                    }
                }
            }
            domcom_initialize_profile_effect = yes
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_parentage_child }
                change_variable = { name = domcom_ui_blood_count add = 1 }
            }
        }
    }

    # Cheap incremental catch for anyone born since the last scan: legal children and the children of
    # current intimates. The deep scan is what guarantees completeness; this only keeps an open ledger
    # current between scans.
    every_child = {
        limit = {
            is_alive = yes
            domcom_is_unacknowledged_blood_trigger = yes
            NOT = { has_character_flag = domcom_blood_registered }
        }
        save_temporary_scope_as = domcom_ui_blood_child
        add_character_flag = domcom_blood_registered
        domcom_initialize_profile_effect = yes
        scope:domcom_ui_patron = {
            add_to_variable_list = { name = domcom_blood_registry target = scope:domcom_ui_blood_child }
            add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_blood_child }
            change_variable = { name = domcom_ui_blood_count add = 1 }
        }
    }
    every_relation = {
        type = lover
        type = soulmate
        limit = { is_alive = yes }
        every_child = {
            limit = {
                is_alive = yes
                domcom_is_unacknowledged_blood_trigger = yes
                NOT = { has_character_flag = domcom_blood_registered }
            }
            save_temporary_scope_as = domcom_ui_blood_child
            add_character_flag = domcom_blood_registered
            domcom_initialize_profile_effect = yes
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_blood_registry target = scope:domcom_ui_blood_child }
                add_to_variable_list = { name = domcom_ui_blood_raw target = scope:domcom_ui_blood_child }
                change_variable = { name = domcom_ui_blood_count add = 1 }
            }
        }
    }

    # ISSUE 5 — the Tantalized roster. Obedience has always been tracked on the subject; nothing ever
    # collected it for display.
    set_variable = { name = domcom_ui_tantalized_count value = 0 }
    set_variable = { name = domcom_ui_tantalized_women value = 0 }
    set_variable = { name = domcom_ui_tantalized_men value = 0 }
    set_variable = { name = domcom_ui_pet_count value = 0 }
    clear_variable_list = domcom_ui_tantalized_raw
    clear_variable_list = domcom_ui_tantalized
    clear_variable_list = domcom_ui_cucked_page_list
    clear_variable_list = domcom_ui_owned_page_list
    clear_variable_list = domcom_ui_endowments_page_list
    clear_variable_list = domcom_ui_outcomes_page_list
    clear_variable_list = domcom_ui_lovers_page_list
    clear_variable_list = domcom_ui_prospects_page_list
    clear_variable_list = domcom_ui_blood_page_list
    clear_variable_list = domcom_ui_tantalized_page_list
    clear_variable_list = domcom_ui_secrets_page_list
    clear_variable_list = domcom_lick_page_list
    if = {
        limit = { has_variable_list = domcom_tantalized_registry }
        every_in_list = {
            variable = domcom_tantalized_registry
            limit = {
                is_alive = yes
                has_variable = domcom_obedience_patron
                var:domcom_obedience_patron = scope:domcom_ui_patron
            }
            domcom_initialize_profile_effect = yes
            save_temporary_scope_as = domcom_ui_tantalized_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_tantalized_raw target = scope:domcom_ui_tantalized_subject }
                change_variable = { name = domcom_ui_tantalized_count add = 1 }
            }
            if = { limit = { is_female = yes } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_tantalized_women add = 1 } } }
            else_if = { limit = { is_male = yes } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_tantalized_men add = 1 } } }
            if = { limit = { has_character_flag = domcom_pet } scope:domcom_ui_patron = { change_variable = { name = domcom_ui_pet_count add = 1 } } }
        }
    }

    # World Cucks is lazy: only collect the lightweight reference roster when this is the page the player
    # is actually looking at.
    if = {
        limit = {
            exists = var:domcom_ui_page
            var:domcom_ui_page = flag:world_cucks
        }
        domcom_collect_world_cuck_roster_effect = yes
    }

    # If the Ledger reopens on World Outcomes, refresh the observational roster immediately instead of
    # showing the cached list from the previous opening.
    if = {
        limit = {
            exists = var:domcom_ui_page
            var:domcom_ui_page = flag:outcomes
        }
        domcom_prepare_world_outcomes_roster_effect = yes
    }

    domcom_rebuild_ui_rosters_effect = yes
}

# Rebuild only the display rosters. Sorting/filtering never performs expensive world-profile maintenance;
# World Cucks only sorts its lightweight cache.
# Sort/filter operations always return every paged roster to page 1. This prevents Reverse from
# appearing to do nothing simply because the player remained in the middle/end of the old ordering.
domcom_reset_ui_paging_effect = {
    set_variable = { name = domcom_ui_cucked_page value = 0 }
    set_variable = { name = domcom_ui_world_page value = 0 }
    set_variable = { name = domcom_ui_owned_page value = 0 }
    set_variable = { name = domcom_ui_endowments_page value = 0 }
    set_variable = { name = domcom_ui_lovers_page value = 0 }
    set_variable = { name = domcom_ui_prospects_page value = 0 }
    set_variable = { name = domcom_ui_blood_page value = 0 }
    set_variable = { name = domcom_ui_tantalized_page value = 0 }
    set_variable = { name = domcom_ui_secrets_page value = 0 }
}

domcom_rebuild_ui_rosters_effect = {
    clear_variable_list = domcom_ui_cucked_subjects
    clear_variable_list = domcom_ui_world_cucks
    clear_variable_list = domcom_ui_owned_subjects
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_prospects
    clear_variable_list = domcom_ui_blood_children
    clear_variable_list = domcom_ui_tantalized
    clear_variable_list = domcom_ui_cucked_page_list
    clear_variable_list = domcom_ui_owned_page_list
    clear_variable_list = domcom_ui_endowments_page_list
    clear_variable_list = domcom_ui_outcomes_page_list
    clear_variable_list = domcom_ui_lovers_page_list
    clear_variable_list = domcom_ui_prospects_page_list
    clear_variable_list = domcom_ui_blood_page_list
    clear_variable_list = domcom_ui_tantalized_page_list
    clear_variable_list = domcom_ui_secrets_page_list
    clear_variable_list = domcom_lick_page_list
    set_variable = { name = domcom_ui_filtered_cucked_count value = 0 }
    set_variable = { name = domcom_ui_filtered_owned_count value = 0 }
    save_scope_as = domcom_ui_patron

    if = {
        limit = {
            has_variable_list = domcom_ui_world_cucks_raw
            exists = var:domcom_ui_page
            var:domcom_ui_page = flag:world_cucks
        }
        domcom_rebuild_world_cuck_roster_effect = yes
    }

    if = {
        limit = { has_variable_list = domcom_ui_cucked_raw }
        if = { limit = { var:domcom_ui_sort_mode = flag:endowment } domcom_rebuild_cucked_endowment_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:alpha } domcom_rebuild_cucked_alpha_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:xp } domcom_rebuild_cucked_xp_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_rebuild_cucked_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_rebuild_cucked_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_rebuild_cucked_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_rebuild_cucked_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_rebuild_cucked_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_rebuild_cucked_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_rebuild_cucked_total_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prize } domcom_rebuild_cucked_prize_effect = yes }
        else = { domcom_rebuild_cucked_rank_effect = yes }
    }
    if = {
        limit = { has_variable_list = domcom_ui_owned_raw }
        if = { limit = { var:domcom_ui_sort_mode = flag:endowment } domcom_rebuild_owned_endowment_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:tribute } domcom_rebuild_owned_tribute_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:xp } domcom_rebuild_owned_xp_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_rebuild_owned_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_rebuild_owned_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_rebuild_owned_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_rebuild_owned_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_rebuild_owned_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_rebuild_owned_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_rebuild_owned_total_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prize } domcom_rebuild_owned_prize_effect = yes }
        else = { domcom_rebuild_owned_rank_effect = yes }
    }
    if = {
        limit = {
            has_variable_list = domcom_ui_endowments_raw
            exists = var:domcom_ui_page
            var:domcom_ui_page = flag:endowments
        }
        if = {
            limit = { has_variable = domcom_ui_endowment_view var:domcom_ui_endowment_view = flag:women }
            if = { limit = { var:domcom_ui_sort_mode = flag:pref_length } domcom_order_preferences_length_effect = yes }
            else_if = { limit = { var:domcom_ui_sort_mode = flag:pref_girth } domcom_order_preferences_girth_effect = yes }
            else = { domcom_order_preferences_both_effect = yes }
        }
        else_if = {
            limit = { has_variable = domcom_ui_endowment_view var:domcom_ui_endowment_view = flag:breasts }
            if = { limit = { var:domcom_ui_sort_mode = flag:bust } domcom_order_breasts_bust_effect = yes }
            else_if = { limit = { var:domcom_ui_sort_mode = flag:underbust } domcom_order_breasts_underbust_effect = yes }
            else_if = { limit = { var:domcom_ui_sort_mode = flag:breast_mastery } domcom_order_breasts_mastery_effect = yes }
            else = { domcom_order_breasts_fullness_effect = yes }
        }
        else_if = {
            limit = { has_variable = domcom_ui_endowment_view var:domcom_ui_endowment_view = flag:breast_prefs }
            if = { limit = { var:domcom_ui_sort_mode = flag:pref_breast_fullness } domcom_order_breast_preferences_fullness_effect = yes }
            else_if = { limit = { var:domcom_ui_sort_mode = flag:pref_breast_frame } domcom_order_breast_preferences_frame_effect = yes }
            else = { domcom_order_breast_preferences_both_effect = yes }
        }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:endowment } domcom_order_endowments_endowment_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:mastery } domcom_order_endowments_mastery_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:length } domcom_order_endowments_length_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:girth } domcom_order_endowments_girth_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_order_endowments_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_order_endowments_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_order_endowments_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_order_endowments_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_order_endowments_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_order_endowments_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_order_endowments_total_effect = yes }
        else = { domcom_order_endowments_rank_effect = yes }
    }
    if = {
        limit = { has_variable_list = domcom_ui_prospects_raw }
        if = { limit = { var:domcom_ui_sort_mode = flag:endowment } domcom_order_prospects_endowment_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_order_prospects_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_order_prospects_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_order_prospects_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_order_prospects_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_order_prospects_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_order_prospects_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_order_prospects_total_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prize } domcom_order_prospects_prize_effect = yes }
        else = { domcom_order_prospects_rank_effect = yes }
    }
    if = {
        limit = { has_variable_list = domcom_ui_tantalized_raw }
        domcom_order_tantalized_effect = yes
    }
    if = {
        limit = { has_variable_list = domcom_ui_blood_raw }
        if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_order_blood_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_order_blood_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_order_blood_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_order_blood_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_order_blood_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_order_blood_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_order_blood_total_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prize } domcom_order_blood_prize_effect = yes }
        else = { domcom_order_blood_rank_effect = yes }
    }

    domcom_build_standard_ui_pages_effect = yes
}

# Women's preference ordering shares the standard Endowment page/pagination but filters adult women
# with stored preference measurements. Reverse has the same semantics as the physical registry.
domcom_order_preferences_length_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_length_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_length_value limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_preferences_girth_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_girth_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_girth_value limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_preferences_both_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_both_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_both_value limit = { is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes has_variable = domcom_pref_length_tenths has_variable = domcom_pref_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

# Each ordered-list helper uses the same filter and flips the order value when Reverse is active.
domcom_rebuild_cucked_rank_effect = { domcom_order_cucked_rank_effect = yes }
domcom_rebuild_cucked_alpha_effect = { domcom_order_cucked_alpha_effect = yes }
domcom_rebuild_cucked_xp_effect = { domcom_order_cucked_xp_effect = yes }
domcom_rebuild_cucked_diplomacy_effect = { domcom_order_cucked_diplomacy_effect = yes }
domcom_rebuild_cucked_martial_effect = { domcom_order_cucked_martial_effect = yes }
domcom_rebuild_cucked_stewardship_effect = { domcom_order_cucked_stewardship_effect = yes }
domcom_rebuild_cucked_intrigue_effect = { domcom_order_cucked_intrigue_effect = yes }
domcom_rebuild_cucked_learning_effect = { domcom_order_cucked_learning_effect = yes }
domcom_rebuild_cucked_prowess_effect = { domcom_order_cucked_prowess_effect = yes }
domcom_rebuild_owned_rank_effect = { domcom_order_owned_rank_effect = yes }
domcom_rebuild_owned_tribute_effect = { domcom_order_owned_tribute_effect = yes }
domcom_rebuild_owned_xp_effect = { domcom_order_owned_xp_effect = yes }
domcom_rebuild_owned_diplomacy_effect = { domcom_order_owned_diplomacy_effect = yes }
domcom_rebuild_owned_martial_effect = { domcom_order_owned_martial_effect = yes }
domcom_rebuild_owned_stewardship_effect = { domcom_order_owned_stewardship_effect = yes }
domcom_rebuild_owned_intrigue_effect = { domcom_order_owned_intrigue_effect = yes }
domcom_rebuild_owned_learning_effect = { domcom_order_owned_learning_effect = yes }
domcom_rebuild_owned_prowess_effect = { domcom_order_owned_prowess_effect = yes }

# Macro-expanded helpers. `ordered_in_list` is the documented CK3 path for custom-sorted GUI variable
# lists.
domcom_order_endowments_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_rank_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_rank_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_endowment_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_length_sort_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_length_sort_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_mastery_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_endowment_mastery_sort_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_endowment_mastery_sort_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_length_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_length_sort_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_length_sort_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_girth_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_girth_sort_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_girth_sort_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_diplomacy_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_diplomacy_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_martial_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_martial_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_stewardship_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_stewardship_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_intrigue_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_intrigue_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_learning_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_learning_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_prowess_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_prowess_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_endowments_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_total_value multiply = -1 } limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_total_value limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_cucked_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_sort_rank_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_sort_rank_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_alpha_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_sort_alpha_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_sort_alpha_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_xp_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_sort_xp_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_sort_xp_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = diplomacy multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = diplomacy limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = martial multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = martial limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = stewardship multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = stewardship limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = intrigue multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = intrigue limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = learning multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = learning limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_cucked_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = prowess multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = prowess limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_owned_xp_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_sort_xp_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_sort_xp_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = diplomacy multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = diplomacy limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = martial multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = martial limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = stewardship multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = stewardship limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = intrigue multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = intrigue limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = learning multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = learning limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = prowess multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = prowess limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_sort_rank_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_sort_rank_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_owned_tribute_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_sort_tribute_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_sort_tribute_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}


# Prospects and Children use the same skill/rank sorting controls without rank filters.
domcom_order_prospects_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = domcom_sort_rank_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = domcom_sort_rank_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = diplomacy multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = diplomacy max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = martial multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = martial max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = stewardship multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = stewardship max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = intrigue multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = intrigue max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = learning multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = learning max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_prospects_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = prowess multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = prowess max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = domcom_sort_rank_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = domcom_sort_rank_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = diplomacy multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = diplomacy max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = martial multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = martial max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = stewardship multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = stewardship max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = intrigue multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = intrigue max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = learning multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = learning max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}
domcom_order_blood_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = prowess multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = prowess max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}

# Collect one year's tribute immediately. The subject pays first; a shortfall is collected from wealthy
# adult vassals, courtiers, and close/extended family.
domcom_demand_annual_tribute_effect = {
    save_scope_as = domcom_tribute_advance_subject
    var:domcom_patron = { save_scope_as = domcom_tribute_advance_patron }
    set_variable = { name = domcom_tribute_advance_shortfall value = domcom_annual_tribute_due_value }
    set_variable = { name = domcom_tribute_advance_collected value = 0 }

    if = {
        limit = { var:domcom_tribute_advance_shortfall > 0 gold > 0 }
        set_variable = { name = domcom_tribute_piece value = gold }
        if = { limit = { var:domcom_tribute_piece > var:domcom_tribute_advance_shortfall } set_variable = { name = domcom_tribute_piece value = var:domcom_tribute_advance_shortfall } }
        pay_short_term_gold = { target = scope:domcom_tribute_advance_patron gold = var:domcom_tribute_piece }
        change_variable = { name = domcom_tribute_advance_collected add = var:domcom_tribute_piece }
        change_variable = { name = domcom_tribute_advance_shortfall subtract = var:domcom_tribute_piece }
    }

    every_vassal = {
        limit = { is_alive = yes age >= 18 gold > 0 }
        add_to_temporary_list = domcom_tribute_advance_network
    }
    every_courtier_or_guest = {
        limit = { is_alive = yes age >= 18 gold > 0 NOT = { is_in_list = domcom_tribute_advance_network } }
        add_to_temporary_list = domcom_tribute_advance_network
    }
    every_close_or_extended_family_member = {
        limit = { is_alive = yes age >= 18 gold > 0 NOT = { is_in_list = domcom_tribute_advance_network } }
        add_to_temporary_list = domcom_tribute_advance_network
    }

    ordered_in_list = {
        list = domcom_tribute_advance_network
        order_by = gold
        max = 100
        check_range_bounds = no
        limit = { scope:domcom_tribute_advance_subject = { var:domcom_tribute_advance_shortfall > 0 } gold > 0 }
        save_temporary_scope_as = domcom_network_payer
        set_variable = { name = domcom_network_tribute_piece value = gold }
        if = {
            limit = { var:domcom_network_tribute_piece > scope:domcom_tribute_advance_subject.var:domcom_tribute_advance_shortfall }
            set_variable = { name = domcom_network_tribute_piece value = scope:domcom_tribute_advance_subject.var:domcom_tribute_advance_shortfall }
        }
        pay_short_term_gold = { target = scope:domcom_tribute_advance_patron gold = var:domcom_network_tribute_piece }
        add_opinion = { target = scope:domcom_tribute_advance_subject modifier = domcom_forced_to_cover_tribute_opinion }
        scope:domcom_tribute_advance_subject = {
            change_variable = { name = domcom_tribute_advance_collected add = scope:domcom_network_payer.var:domcom_network_tribute_piece }
            change_variable = { name = domcom_tribute_advance_shortfall subtract = scope:domcom_network_payer.var:domcom_network_tribute_piece }
        }
    }
    # If the subject and their network still cannot cover the annual demand, the subject is driven into
    # debt rather than the patron silently forgiving it.
    if = {
        limit = { var:domcom_tribute_advance_shortfall > 0 }
        scope:domcom_tribute_advance_patron = { add_gold = { value = scope:domcom_tribute_advance_subject.var:domcom_tribute_advance_shortfall } }
        add_gold = { value = var:domcom_tribute_advance_shortfall multiply = -1 }
        change_variable = { name = domcom_tribute_advance_collected add = var:domcom_tribute_advance_shortfall }
        set_variable = { name = domcom_tribute_advance_shortfall value = 0 }
    }
    add_character_flag = { flag = domcom_tribute_prepaid years = 1 }
}

domcom_own_cuck_from_ui_effect = {
    scope:domcom_ui_patron = { save_scope_as = domcom_owner }
    if = { limit = { NOT = { has_character_flag = domcom_owned_cuck } } domcom_own_cuck_generic_effect = yes }
    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
    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
}

# AI succession pressure: if an Owned ruler's primary heir is the AI patron's acknowledged child, the AI
# may press the same abdication demand available to players.
domcom_ai_manage_succession_effect = {
    save_scope_as = domcom_ai_succession_patron
    if = {
        limit = { exists = dynasty dynasty = { has_variable_list = domcom_owned_subjects } }
        dynasty = {
            random_in_list = {
                variable = domcom_owned_subjects
                limit = {
                    is_alive = yes is_landed = yes
                    has_character_flag = domcom_owned_cuck
                    has_variable = domcom_patron
                    var:domcom_patron = scope:domcom_ai_succession_patron
                    domcom_can_demand_abdication_for_blood_trigger = { PATRON = scope:domcom_ai_succession_patron }
                }
                save_scope_as = domcom_ai_abdication_target
            }
        }
        if = {
            limit = { exists = scope:domcom_ai_abdication_target }
            scope:domcom_ai_succession_patron = { save_scope_as = domcom_abdication_patron }
            scope:domcom_ai_abdication_target = {
                add_character_flag = domcom_ai_abdication_failed_roll
                random = {
                    chance = domcom_abdication_chance_value
                    remove_character_flag = domcom_ai_abdication_failed_roll
                    if = {
                        # A human subject is never silently stripped of the realm. Winning the pressure
                        # roll creates a personal ultimatum.
                        limit = { is_ai = no }
                        add_character_flag = { flag = domcom_blood_abdication_pending months = 6 }
                        trigger_event = { id = domcom.930 days = 1 }
                    }
                    else = {
                        domcom_abdicate_to_blood_effect = yes
                    }
                }
                if = {
                    limit = { has_character_flag = domcom_ai_abdication_failed_roll }
                    remove_character_flag = domcom_ai_abdication_failed_roll
                    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 0 } }
                    change_variable = { name = domcom_cuck_xp add = 100 }
                    domcom_refresh_cuck_stage_effect = yes
                }
            }
        }
    }
}

domcom_player_wins_blood_duel_effect = {
    remove_character_flag = domcom_blood_abdication_pending
    add_character_flag = { flag = domcom_blood_abdication_immunity years = 5 }
    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
    change_variable = { name = domcom_cuck_xp subtract = 150 }
    if = { limit = { var:domcom_cuck_xp < 100 } set_variable = { name = domcom_cuck_xp value = 100 } }
    domcom_refresh_cuck_stage_effect = yes
}

# A successful defense of the succession war is an even stronger reversal.
domcom_player_wins_blood_war_effect = {
    remove_character_flag = domcom_blood_abdication_pending
    add_character_flag = { flag = domcom_blood_abdication_immunity years = 5 }
    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
    change_variable = { name = domcom_cuck_xp subtract = 200 }
    if = { limit = { var:domcom_cuck_xp < 100 } set_variable = { name = domcom_cuck_xp value = 100 } }
    domcom_refresh_cuck_stage_effect = yes
}

# Run from the AI Patron with scope:domcom_blood_war_defender saved.
domcom_start_blood_succession_war_effect = {
    if = {
        limit = {
            is_alive = yes
            is_landed = yes
            exists = scope:domcom_blood_war_defender
            scope:domcom_blood_war_defender = { is_alive = yes is_landed = yes }
        }
        start_war = {
            cb = domcom_blood_succession_war
            target = scope:domcom_blood_war_defender
        }
    }
}

domcom_ai_acknowledge_blood_effect = {
    save_scope_as = domcom_ack_patron
    random_child = {
        limit = {
            is_alive = yes
            OR = { father ?= scope:domcom_ack_patron mother ?= scope:domcom_ack_patron real_father ?= scope:domcom_ack_patron }
            trigger_if = {
                limit = { exists = scope:domcom_ack_patron.house }
                OR = { NOT = { exists = house } NOT = { house = scope:domcom_ack_patron.house } }
            }
        }
        domcom_acknowledge_child_effect = yes
    }
}


# Run from the hegemon. Builds a one-pass roster of direct landed vassals.
domcom_begin_imperial_tribute_effect = {
    clear_variable_list = domcom_tribute_pending
    set_variable = { name = domcom_tribute_pending_count value = 0 }
    set_variable = { name = domcom_tribute_summoned_count value = 0 }
    # Per-season counters. These are the ones the Tribute page reports and the only ones a new season may
    # reset.
    set_variable = { name = domcom_tribute_gold_count value = 0 }
    set_variable = { name = domcom_tribute_prestige_count value = 0 }
    set_variable = { name = domcom_tribute_military_count value = 0 }
    set_variable = { name = domcom_tribute_dynastic_count value = 0 }
    set_variable = { name = domcom_tribute_household_season_count value = 0 }
    set_variable = { name = domcom_tribute_refusal_season_count value = 0 }
    # domcom_tribute_household_count and domcom_tribute_refusal_count are LIFETIME ledger counters and
    # are never reset here; zeroing them on every summons was wiping the career record the Ledger page
    # reads.
    domcom_initialize_ledger_counters_effect = yes
    add_character_flag = domcom_tribute_season_active
    every_vassal = {
        limit = { is_alive = yes domcom_is_political_vassal_ruler_trigger = yes }
        save_temporary_scope_as = domcom_tribute_vassal_to_add
        root = {
            add_to_variable_list = { name = domcom_tribute_pending target = scope:domcom_tribute_vassal_to_add }
            change_variable = { name = domcom_tribute_pending_count add = 1 }
        }
    }
    set_variable = { name = domcom_tribute_total_count value = var:domcom_tribute_pending_count }
    trigger_event = { id = domcom.500 days = 5 }
}

# Run from the patron when advancing the season.
domcom_advance_imperial_tribute_effect = {
    if = {
        limit = { has_character_flag = domcom_tribute_season_active has_variable_list = domcom_tribute_pending }

        # Drop petitioners who can no longer appear (dead, unlanded, no longer my vassal) and recount
        # from what is actually left, so the page never advertises an audience that will never happen.
        save_scope_as = domcom_tribute_prune_patron
        every_in_list = {
            variable = domcom_tribute_pending
            limit = { NOT = { AND = { is_alive = yes domcom_is_political_vassal_ruler_trigger = yes is_vassal_of = scope:domcom_tribute_prune_patron } } }
            save_temporary_scope_as = domcom_tribute_stale
            scope:domcom_tribute_prune_patron = {
                remove_list_variable = { name = domcom_tribute_pending target = scope:domcom_tribute_stale }
            }
        }
        set_variable = { name = domcom_tribute_pending_count value = 0 }
        every_in_list = {
            variable = domcom_tribute_pending
            scope:domcom_tribute_prune_patron = { change_variable = { name = domcom_tribute_pending_count add = 1 } }
        }

        random_in_list = {
            variable = domcom_tribute_pending
            limit = { is_alive = yes domcom_is_political_vassal_ruler_trigger = yes is_vassal_of = root }
            save_scope_as = domcom_tribute_vassal
        }
        if = {
            limit = { exists = scope:domcom_tribute_vassal }
            remove_list_variable = { name = domcom_tribute_pending target = scope:domcom_tribute_vassal }
            change_variable = { name = domcom_tribute_pending_count subtract = 1 }
            change_variable = { name = domcom_tribute_summoned_count add = 1 }
            save_scope_as = domcom_tribute_patron
            scope:domcom_tribute_vassal = { trigger_event = { id = domcom.510 days = 1 } }
        }
        else = { domcom_close_tribute_season_effect = yes }
    }
    else_if = {
        limit = { has_character_flag = domcom_tribute_season_active }
        domcom_close_tribute_season_effect = yes
    }
}

# Run from the vassal after choosing a tribute. Schedules the next petitioner.
domcom_finish_tribute_petition_effect = {
    if = {
        limit = { exists = scope:domcom_tribute_patron scope:domcom_tribute_patron = { is_alive = yes } }
        scope:domcom_tribute_patron = {
            if = {
                limit = { has_variable = domcom_tribute_pending_count var:domcom_tribute_pending_count > 0 }
                trigger_event = { id = domcom.500 days = { 30 90 } }
            }
            else = { domcom_close_tribute_season_effect = yes }
        }
    }
}

# Add rank-scaled humiliation when an imperial household offering compromises a marriage. Run from the
# cuck with scope:domcom_tribute_patron and scope:domcom_tribute_vassal saved.
domcom_add_household_tribute_cuck_xp_effect = {
    if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
    change_variable = { name = domcom_cuck_xp add = 50 }
    if = { limit = { scope:domcom_tribute_vassal = { highest_held_title_tier = tier_duchy } } change_variable = { name = domcom_cuck_xp add = 50 } }
    else_if = { limit = { scope:domcom_tribute_vassal = { highest_held_title_tier = tier_kingdom } } change_variable = { name = domcom_cuck_xp add = 125 } }
    else_if = { limit = { scope:domcom_tribute_vassal = { highest_held_title_tier >= tier_empire } } change_variable = { name = domcom_cuck_xp add = 200 } }
    domcom_refresh_cuck_stage_effect = yes
    domcom_check_final_collapse_effect = yes
}

# Run from a vassal with scope:domcom_tribute_patron saved.
domcom_select_household_tribute_offering_effect = {
    save_scope_as = domcom_tribute_vassal
    if = {
        limit = {
            age >= 18 is_alive = yes
            scope:domcom_tribute_patron = { is_attracted_to_gender_of = prev }
            is_attracted_to_gender_of = scope:domcom_tribute_patron
            NOT = { AND = { has_character_flag = domcom_household_guarded scope:domcom_tribute_patron = { is_ai = yes } } }
        }
        add_to_temporary_list = domcom_household_tribute_candidates
    }
    every_spouse = {
        limit = {
            is_alive = yes age >= 18
            scope:domcom_tribute_patron = { is_attracted_to_gender_of = prev }
            is_attracted_to_gender_of = scope:domcom_tribute_patron
            NOT = { AND = { has_character_flag = domcom_household_guarded scope:domcom_tribute_patron = { is_ai = yes } } }
        }
        add_to_temporary_list = domcom_household_tribute_candidates
    }
    every_child = {
        limit = {
            is_alive = yes age >= 18
            scope:domcom_tribute_patron = { is_attracted_to_gender_of = prev }
            is_attracted_to_gender_of = scope:domcom_tribute_patron
            NOT = { AND = { has_character_flag = domcom_household_guarded scope:domcom_tribute_patron = { is_ai = yes } } }
        }
        add_to_temporary_list = domcom_household_tribute_candidates
    }
    random_in_list = {
        list = domcom_household_tribute_candidates
        save_scope_as = domcom_household_offering
    }
}

# Run from the selected adult offering.
domcom_resolve_household_tribute_effect = {
    save_scope_as = domcom_household_offering
    scope:domcom_tribute_patron = { save_scope_as = domcom_admirer_patron }
    domcom_consummate_admirer_effect = yes
    if = {
        limit = { has_character_flag = domcom_admirer_intercepted_by_guard }
        # The tribute attempt has become a pending household challenge; do not award tribute benefits or
        # Cuck XP until actual intimacy occurs through the confrontation system.
        remove_character_flag = domcom_admirer_intercepted_by_guard
    }
    else = {
    # A married offering compromises every other spouse in the relationship.
    every_spouse = {
        limit = {
            is_alive = yes age >= 18
            NOT = { this = scope:domcom_tribute_patron }
            scope:domcom_household_offering = { NOT = { is_consort_of = scope:domcom_tribute_patron } }
        }
        save_scope_as = domcom_household_tribute_cuck
        if = {
            limit = {
                has_character_flag = domcom_cucked
                OR = {
                    AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_tribute_patron }
                    AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_tribute_patron }
                }
            }
            domcom_add_household_tribute_cuck_xp_effect = yes
        }
        else = {
            scope:domcom_tribute_patron = { save_scope_as = domcom_owner }
            domcom_register_cuck_generic_effect = yes
            domcom_add_household_tribute_cuck_xp_effect = yes
        }
    }

    scope:domcom_tribute_vassal = {
        add_prestige = 100
        add_opinion = { target = scope:domcom_tribute_patron modifier = domcom_imperial_household_tribute_opinion }
        add_character_modifier = { modifier = domcom_imperial_favor_modifier years = 5 }
    }
    if = {
        limit = { exists = scope:domcom_tribute_patron.dynasty }
        scope:domcom_tribute_patron.dynasty = { add_dynasty_prestige = 25 }
    }
    scope:domcom_tribute_patron = { change_variable = { name = domcom_tribute_household_count add = 1 } change_variable = { name = domcom_tribute_household_season_count add = 1 } }

    }
}

# AI parity: notable AI hegemons may open their own tribute season.
domcom_ai_try_start_tribute_season_effect = {
    if = {
        limit = { domcom_can_summon_imperial_tribute_trigger = yes }
        random = {
            chance = 12
            domcom_begin_imperial_tribute_effect = yes
        }
    }
}


domcom_ai_try_general_alpha_effect = {
    save_scope_as = domcom_ai_patron
    domcom_initialize_profile_effect = yes
    random = {
        chance = domcom_ai_general_alpha_activity_chance_value

        # Previously every vassal always challenged their liege first, which made AI Alpha behavior both
        # rare and repetitive. Choose among liege, own vassals, and fellow vassals instead.
        random_list = {
            30 = {
                trigger = {
                    exists = liege
                    liege = {
                        is_alive = yes age >= 18 is_imprisoned = no
                        NOT = { has_character_flag = domcom_collapse_resolved }
                        sex_same_as = scope:domcom_ai_patron
                    }
                }
                liege = { save_scope_as = domcom_ai_general_target }
            }
            45 = {
                trigger = {
                    any_vassal = {
                        is_alive = yes age >= 18 is_imprisoned = no
                        NOT = { has_character_flag = domcom_collapse_resolved }
                        sex_same_as = scope:domcom_ai_patron
                    }
                }
                random_vassal = {
                    limit = {
                        is_alive = yes age >= 18 is_imprisoned = no
                        NOT = { has_character_flag = domcom_collapse_resolved }
                        sex_same_as = scope:domcom_ai_patron
                    }
                    save_scope_as = domcom_ai_general_target
                }
            }
            25 = {
                trigger = {
                    exists = liege
                    liege = {
                        any_vassal = {
                            is_alive = yes age >= 18 is_imprisoned = no
                            NOT = { this = scope:domcom_ai_patron }
                            NOT = { has_character_flag = domcom_collapse_resolved }
                            sex_same_as = scope:domcom_ai_patron
                        }
                    }
                }
                liege = {
                    random_vassal = {
                        limit = {
                            is_alive = yes age >= 18 is_imprisoned = no
                            NOT = { this = scope:domcom_ai_patron }
                            NOT = { has_character_flag = domcom_collapse_resolved }
                            sex_same_as = scope:domcom_ai_patron
                        }
                        save_scope_as = domcom_ai_general_target
                    }
                }
            }
        }

        if = {
            limit = { exists = scope:domcom_ai_general_target }
            scope:domcom_ai_general_target = {
                domcom_initialize_profile_effect = yes
                random = {
                    chance = domcom_ai_alpha_check_chance_value
                    scope:domcom_ai_patron = { save_scope_as = domcom_owner }
                    if = {
                        limit = {
                            OR = {
                                AND = {
                                    has_character_flag = domcom_cucked
                                    has_variable = domcom_cuck_patron
                                    var:domcom_cuck_patron = scope:domcom_ai_patron
                                }
                                domcom_has_qualifying_cuck_evidence_from_patron_trigger = { PATRON = scope:domcom_ai_patron }
                            }
                        }
                        if = { limit = { NOT = { has_character_flag = domcom_cucked } } domcom_register_cuck_generic_effect = yes }
                        if = { limit = { NOT = { has_character_flag = domcom_owned_cuck } } domcom_own_cuck_generic_effect = yes }
                        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
                    }
                    else = {
                        if = {
                            limit = {
                                NOT = {
                                    AND = { has_character_flag = domcom_dominated has_variable = domcom_dominance_patron var:domcom_dominance_patron = scope:domcom_ai_patron }
                                }
                            }
                            domcom_apply_dominated_effect = yes
                        }
                    }
                }
            }
        }
    }
}


domcom_rebuild_cucked_endowment_effect = { domcom_order_cucked_endowment_effect = yes }
domcom_rebuild_owned_endowment_effect = { domcom_order_owned_endowment_effect = yes }

domcom_order_cucked_endowment_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_length_sort_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_length_sort_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}
domcom_order_owned_endowment_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_length_sort_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_length_sort_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}
domcom_order_prospects_endowment_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = domcom_length_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = domcom_length_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}


# 2.0 retroactive registry reconstruction. The live relationship code now self-heals membership on
# registration; this full scan exists to repair saves created by builds where cache flags/pointers could
# survive while the global or Patron-local lists silently lost the character.
domcom_reconstruct_cuck_registries_effect = {
    save_scope_as = domcom_registry_rebuild_viewer

    every_living_character = {
        limit = {
            age >= 18
            OR = {
                has_character_flag = domcom_cucked
                AND = {
                    OR = { has_trait = domcom_cucked_trait has_variable = domcom_cuck_xp }
                    OR = {
                        has_variable = domcom_cuck_origin_patron
                        has_variable = domcom_cuck_patron
                        has_variable = domcom_cuck_registry_patron
                        has_variable_list = domcom_cuck_patrons
                    }
                }
            }
        }
        save_temporary_scope_as = domcom_registry_rebuild_subject

        # Recover the public state only when surviving Dominion patron/evidence data exists.
        if = { limit = { NOT = { has_character_flag = domcom_cucked } } add_character_flag = domcom_cucked }
        if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
        if = { limit = { var:domcom_cuck_xp <= 0 } set_variable = { name = domcom_cuck_xp value = 100 } }

        # If only an origin/Owned pointer survived, restore the active Patron pointer conservatively.
        if = {
            limit = {
                NOT = { has_variable = domcom_cuck_patron }
                has_variable = domcom_cuck_origin_patron
                var:domcom_cuck_origin_patron = { is_alive = yes NOT = { this = scope:domcom_registry_rebuild_subject } }
            }
            set_variable = { name = domcom_cuck_patron value = var:domcom_cuck_origin_patron }
        }
        else_if = {
            limit = {
                NOT = { has_variable = domcom_cuck_patron }
                has_variable = domcom_patron
                var:domcom_patron = { is_alive = yes NOT = { this = scope:domcom_registry_rebuild_subject } }
            }
            set_variable = { name = domcom_cuck_patron value = var:domcom_patron }
        }

        # Reconstruct historical Patron list from surviving singular pointers.
        if = {
            limit = {
                has_variable = domcom_cuck_origin_patron
                var:domcom_cuck_origin_patron = { is_alive = yes NOT = { this = scope:domcom_registry_rebuild_subject } }
            }
            var:domcom_cuck_origin_patron = { save_temporary_scope_as = domcom_registry_rebuild_patron }
            if = {
                limit = { NOT = { any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_registry_rebuild_patron } } }
                add_to_variable_list = { name = domcom_cuck_patrons target = scope:domcom_registry_rebuild_patron }
            }
        }
        if = {
            limit = {
                has_variable = domcom_cuck_patron
                var:domcom_cuck_patron = { is_alive = yes NOT = { this = scope:domcom_registry_rebuild_subject } }
            }
            var:domcom_cuck_patron = { save_temporary_scope_as = domcom_registry_rebuild_patron }
            if = {
                limit = { NOT = { any_in_list = { variable = domcom_cuck_patrons this = scope:domcom_registry_rebuild_patron } } }
                add_to_variable_list = { name = domcom_cuck_patrons target = scope:domcom_registry_rebuild_patron }
            }
            set_variable = { name = domcom_cuck_registry_patron value = scope:domcom_registry_rebuild_patron }
        }

        # Every historical Patron should be able to find this record in their own Cucked registry.
        if = {
            limit = { has_variable_list = domcom_cuck_patrons }
            every_in_list = {
                variable = domcom_cuck_patrons
                limit = { is_alive = yes NOT = { this = scope:domcom_registry_rebuild_subject } }
                if = {
                    limit = {
                        OR = {
                            NOT = { has_variable_list = domcom_cucked_registry }
                            NOT = { any_in_list = { variable = domcom_cucked_registry this = scope:domcom_registry_rebuild_subject } }
                        }
                    }
                    add_to_variable_list = { name = domcom_cucked_registry target = scope:domcom_registry_rebuild_subject }
                }
            }
        }

        domcom_refresh_cuck_stage_effect = yes
        domcom_refresh_cuck_reputation_effect = yes
    }

    domcom_prune_cuck_registry_effect = yes
}

domcom_reconstruct_terminal_devotion_registries_effect = {
    # Pass one: repair already-numbered terminal subjects first. Their stored numbers raise the Patron/
    # dynasty counters before any unnumbered legacy subject receives a new number.
    every_living_character = {
        limit = {
            age >= 18
            has_character_flag = domcom_pet
            has_variable = domcom_pet_number
            OR = { has_variable = domcom_pet_patron has_variable = domcom_obedience_patron }
        }
        if = {
            limit = { NOT = { has_variable = domcom_pet_patron } has_variable = domcom_obedience_patron }
            set_variable = { name = domcom_pet_patron value = var:domcom_obedience_patron }
        }
        domcom_repair_pet_identity_effect = yes
    }

    # Pass two: discover 1000/1000 legacy terminal states that retained a Patron pointer but never received
    # the Pet/Slave flag, number, nickname or Patron-local registry entry.
    every_living_character = {
        limit = {
            age >= 18
            has_variable = domcom_obedience
            var:domcom_obedience >= 1000
            OR = { has_variable = domcom_obedience_patron has_variable = domcom_pet_patron }
        }
        save_temporary_scope_as = domcom_terminal_rebuild_subject
        if = {
            limit = { NOT = { has_variable = domcom_obedience_patron } has_variable = domcom_pet_patron }
            set_variable = { name = domcom_obedience_patron value = var:domcom_pet_patron }
        }
        if = {
            limit = { NOT = { has_variable = domcom_pet_patron } has_variable = domcom_obedience_patron }
            set_variable = { name = domcom_pet_patron value = var:domcom_obedience_patron }
        }
        if = {
            limit = { has_variable = domcom_pet_patron var:domcom_pet_patron = { is_alive = yes NOT = { this = scope:domcom_terminal_rebuild_subject } } }
            var:domcom_pet_patron = { save_scope_as = domcom_tantalize_patron }
            domcom_refresh_obedience_stage_effect = yes
        }
    }
}

domcom_reconstruct_legacy_relationship_registries_200_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_relationship_registries_reconstructed_200 } }
        domcom_reconstruct_cuck_registries_effect = yes
        domcom_reconstruct_terminal_devotion_registries_effect = yes
        set_global_variable = domcom_relationship_registries_reconstructed_200
    }
}

domcom_initialize_existing_ruler_endowments_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_ruler_endowments_initialized_061_r2 } }
        every_ruler = {
            limit = {
                is_alive = yes
                domcom_should_express_endowment_trigger = yes
                age >= 18
                NOT = { has_variable = domcom_length_tenths }
            }
            domcom_assign_endowment_effect = yes
        }
        set_global_variable = domcom_ruler_endowments_initialized_061_r2
    }
}

domcom_seed_world_endowments_once_effect = {
    if = {
        limit = {
            NOT = { has_global_variable = domcom_world_endowments_seeded_070 }
            NOT = { has_game_rule = domcom_world_seed_off }
        }
        domcom_seed_world_endowments_now_effect = yes
    }
}

# The scan itself, ungated. Only the wrapper above and the rebuild tools call it.
domcom_seed_world_endowments_now_effect = {
    set_global_variable = domcom_world_endowments_seeded_070
    every_living_character = {
        limit = {
            domcom_should_express_endowment_trigger = yes
            age >= 18
            NOT = { has_variable = domcom_length_tenths }
        }
        domcom_assign_endowment_effect = yes
    }
}


domcom_try_initialize_profile_effect = {
    if = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }
}

domcom_initialize_local_population_effect = {
    # The patron themselves.
    domcom_try_initialize_profile_effect = yes

    # Own court. This is the single largest source of visible characters.
    every_courtier = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }

    # Prisoners are held locally and are inspectable.
    every_prisoner = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }

    # Spouses and close family. Cheap and almost always inspected.
    every_spouse = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }
    every_close_family_member = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }

    # Existing intimates, which are exactly the characters Dominion evidence is built from.
    every_relation = {
        type = lover
        type = soulmate
        type = crush
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }

    # Direct vassals and their spouses. Not every_vassal_or_below — that would walk the whole realm for a
    # high-tier ruler and reintroduce the hitch.
    every_vassal = {
        limit = { domcom_needs_profile_init_trigger = yes }
        domcom_initialize_profile_effect = yes
    }
    every_vassal = {
        every_spouse = {
            limit = { domcom_needs_profile_init_trigger = yes }
            domcom_initialize_profile_effect = yes
        }
    }

    # Immediate liege and their spouses, so a vassal player's most visible superiors are covered too.
    if = {
        limit = { exists = liege NOT = { liege = this } }
        liege = {
            domcom_try_initialize_profile_effect = yes
            every_spouse = {
                limit = { domcom_needs_profile_init_trigger = yes }
                domcom_initialize_profile_effect = yes
            }
        }
    }
}


# v1.10 migration: preferred length/girth are now the only authoritative preference state. Existing
# saves keep their exact preferred measurements; only the summary category/trait is repaired.
domcom_migrate_preference_classification_v110_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_preference_classification_migration_v110 } }
        every_living_character = {
            limit = {
                age >= 18
                is_attracted_to_men = yes
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
            }
            if = { limit = { has_variable = domcom_preferred_endowment_index } remove_variable = domcom_preferred_endowment_index }
            domcom_sync_size_preference_trait_effect = yes
        }
        set_global_variable = domcom_preference_classification_migration_v110
    }
}

# v2.3.4 migration: reclassify every measured body and stored Endowment preference against the new
# realistic length-first bands. Measurements and canonical locks are never changed; only derived category,
# index mirror, and visible trait labels are rebuilt once.
domcom_migrate_realistic_endowment_bands_v234_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_realistic_endowment_bands_migration_v234 } }
        every_living_character = {
            limit = {
                is_male = yes age >= 18
                OR = {
                    AND = { has_variable = domcom_canonical_length_tenths has_variable = domcom_canonical_girth_tenths }
                    AND = { has_variable = domcom_locked_length_tenths has_variable = domcom_locked_girth_tenths }
                    AND = { has_variable = domcom_length_tenths has_variable = domcom_girth_tenths }
                }
            }
            domcom_restore_canonical_endowment_effect = yes
            remove_variable = domcom_endowment_category
            remove_variable = domcom_endowment_index
            remove_variable = domcom_locked_endowment_category
            domcom_sync_endowment_trait_effect = yes
        }
        every_living_character = {
            limit = {
                age >= 18 is_attracted_to_men = yes
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
            }
            remove_variable = domcom_preferred_endowment_index
            domcom_sync_size_preference_trait_effect = yes
        }
        set_global_variable = domcom_realistic_endowment_bands_migration_v234
    }
}

# v1.9 migration: repair stale category/index locks in existing saves without changing anybody's stored
# body measurements. Because the tier is now derived from the permanent measurement pair, this is safe
# and idempotent; the global marker merely avoids a repeated world scan.
domcom_migrate_endowment_classification_v19_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_endowment_classification_migration_v19 } }
        every_living_character = {
            limit = {
                is_male = yes age >= 18
                has_variable = domcom_locked_length_tenths
                has_variable = domcom_locked_girth_tenths
            }
            set_variable = { name = domcom_length_tenths value = var:domcom_locked_length_tenths }
            set_variable = { name = domcom_girth_tenths value = var:domcom_locked_girth_tenths }
            remove_variable = domcom_endowment_category
            remove_variable = domcom_endowment_index
            remove_variable = domcom_locked_endowment_category
            domcom_sync_endowment_trait_effect = yes
        }
        set_global_variable = domcom_endowment_classification_migration_v19
    }
}

# v1.10.2 migration: install a second, interaction-proof canonical body record for every existing
# measured adult male. The previous locked pair wins when present; otherwise the currently displayed
# complete pair is preserved. No measurements are rerolled.
domcom_migrate_canonical_endowments_v1102_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_canonical_endowment_migration_v1102 } }
        every_living_character = {
            limit = {
                is_male = yes
                age >= 18
                OR = {
                    AND = { has_variable = domcom_locked_length_tenths has_variable = domcom_locked_girth_tenths }
                    AND = { has_variable = domcom_length_tenths has_variable = domcom_girth_tenths }
                }
            }
            domcom_restore_canonical_endowment_effect = yes
            domcom_sync_endowment_trait_effect = yes
        }
        set_global_variable = domcom_canonical_endowment_migration_v1102
    }
}

domcom_rebuild_display_effect = {
    # v2.6.67 performance: one explicit population pass instead of three. This remains synchronous
    # because the player deliberately requested a rebuild, but body display, preference repair, and
    # optional compatibility migration now share the same traversal.
    every_living_character = {
        # The iterator already traverses the living population. Keep adult-only body work inside the
        # branch rather than filtering the iterator itself so compatibility repair can also touch
        # characters who existed as children when an old save was migrated.
        if = {
            limit = { age >= 18 domcom_should_express_endowment_trigger = yes has_variable = domcom_length_tenths }
            remove_variable = domcom_endowment_category
            remove_variable = domcom_endowment_index
            remove_variable = domcom_locked_endowment_category
            domcom_rebuild_clear_sync_flags_effect = yes
            domcom_assign_endowment_effect = yes
            domcom_initialize_endowment_mastery_effect = yes
        }

        if = {
            limit = { age >= 18 is_attracted_to_men = yes }
            domcom_assign_size_preference_effect = yes
        }
        else_if = {
            limit = { age >= 18 }
            domcom_clear_size_preference_traits_effect = yes
        }

        # Empty in Dominion itself. Compatibility modules may use this only during this explicit pass.
        domcom_external_rebuild_character_sync_effect = yes
    }
}

# Destructive reset. Bodies and Endowment preferences are both wiped and rolled again.
domcom_rebuild_measurements_effect = {
    remove_global_variable = domcom_world_endowments_seeded_070
    remove_global_variable = domcom_ruler_endowments_initialized_061_r2
    every_living_character = {
        limit = { age >= 18 }

        # Preference reset applies to everyone; only characters attracted to men receive a new one below.
        if = { limit = { has_variable = domcom_size_preference_primary } remove_variable = domcom_size_preference_primary }
        if = { limit = { has_variable = domcom_size_preference } remove_variable = domcom_size_preference }
        if = { limit = { has_variable = domcom_size_preference_secondary } remove_variable = domcom_size_preference_secondary }
        if = { limit = { has_variable = domcom_size_preference_tertiary } remove_variable = domcom_size_preference_tertiary }
        if = { limit = { has_variable = domcom_pref_length_tenths } remove_variable = domcom_pref_length_tenths }
        if = { limit = { has_variable = domcom_pref_girth_tenths } remove_variable = domcom_pref_girth_tenths }
        if = { limit = { has_variable = domcom_preferred_endowment_index } remove_variable = domcom_preferred_endowment_index }
        domcom_clear_size_preference_traits_effect = yes

        if = {
            limit = { domcom_should_express_endowment_trigger = yes }
            remove_variable = domcom_length_tenths
            remove_variable = domcom_girth_tenths
            remove_variable = domcom_locked_length_tenths
            remove_variable = domcom_locked_girth_tenths
            remove_variable = domcom_canonical_length_tenths
            remove_variable = domcom_canonical_girth_tenths
            remove_variable = domcom_locked_endowment_category
            remove_variable = domcom_sire_length_tenths
            remove_variable = domcom_sire_girth_tenths
            remove_character_flag = domcom_endowment_locked
            remove_variable = domcom_endowment_category
            remove_variable = domcom_endowment_index
            domcom_rebuild_clear_sync_flags_effect = yes
            domcom_clear_endowment_traits_effect = yes
            domcom_rebuild_clear_external_traits_effect = yes
        }
    }

    # Ungated on purpose: reroll all bodies, then reroll all applicable preferences.
    domcom_seed_world_endowments_now_effect = yes
    every_living_character = {
        limit = { age >= 18 is_attracted_to_men = yes }
        domcom_assign_size_preference_effect = yes
    }
    set_global_variable = domcom_ruler_endowments_initialized_061_r2
    set_global_variable = domcom_size_preference_measurement_migration_120
}



domcom_refresh_feminized_reputation_effect = {
    if = {
        limit = { OR = { has_character_flag = domcom_feminized has_trait = domcom_feminized_trait } }
        if = { limit = { NOT = { has_character_flag = domcom_feminized } } add_character_flag = domcom_feminized }
        if = { limit = { NOT = { has_trait = domcom_feminized_trait } } add_trait = domcom_feminized_trait }
        if = { limit = { NOT = { has_character_modifier = domcom_feminized_submission_modifier } } add_character_modifier = domcom_feminized_submission_modifier }
        if = {
            limit = {
                NOR = {
                    has_nickname = nick_domcom_the_remade
                    has_nickname = nick_domcom_the_unmanned
                    has_nickname = nick_domcom_the_softened
                }
            }
            random_list = {
                40 = { give_nickname = nick_domcom_the_remade }
                35 = { give_nickname = nick_domcom_the_unmanned }
                25 = { give_nickname = nick_domcom_the_softened }
            }
        }
    }

    domcom_external_feminized_sync_effect = yes
}


# v2.4.2: Dominion is still allowed to replace an existing public nickname when a character is
# legitimately Cucked.  What changes is that we remember the vanilla Blood-Father/Blood-Mother title
# before replacing it, so an impossible self/lawful-partner cuck repair can put that achievement back.
# CK3 exposes the Strengthen Bloodline nickname under the shared key nick_the_blood_motherfather.
domcom_mark_displaced_nickname_before_cuck_effect = {
    # CK3's script API can test a specific nickname and give a specific nickname, but it exposes no
    # dynamic "current nickname key" scope. Store every nickname key Dominion itself can create plus
    # the vanilla Blood-Father/Blood-Mother achievement. Unknown third-party/other vanilla IDs cannot
    # be losslessly serialized by script; see CHANGELOG_2.4.3 for the limitation.
    if = { limit = { has_nickname = nick_the_blood_motherfather } add_character_flag = domcom_restore_nick_blood_motherfather }
    else_if = { limit = { has_nickname = nick_domcom_the_remade } add_character_flag = domcom_restore_nick_the_remade }
    else_if = { limit = { has_nickname = nick_domcom_the_unmanned } add_character_flag = domcom_restore_nick_the_unmanned }
    else_if = { limit = { has_nickname = nick_domcom_the_softened } add_character_flag = domcom_restore_nick_the_softened }
    else_if = { limit = { has_nickname = nick_domcom_dynasty_slave } add_character_flag = domcom_restore_nick_dynasty_slave }
    else_if = { limit = { has_nickname = nick_domcom_personal_slave } add_character_flag = domcom_restore_nick_personal_slave }
    else_if = { limit = { has_any_nickname = yes } add_character_flag = domcom_displaced_unknown_nickname }
}

# Run only after a bad Dominion Cucked nickname was actually removed.  The stored flag is authoritative
# for records created on 2.4.2+.  The Strong Blood/congenital fallback exists only for already-damaged
# 2.4.1 saves, where Dominion had no previous-nickname storage yet.
domcom_restore_displaced_nickname_after_bad_cuck_effect = {
    if = {
        limit = { has_character_flag = domcom_cuck_nickname_removed_by_repair }
        if = {
            limit = { has_character_flag = domcom_restore_nick_blood_motherfather }
            give_nickname = nick_the_blood_motherfather
            remove_character_flag = domcom_restore_nick_blood_motherfather
        }
        else_if = { limit = { has_character_flag = domcom_restore_nick_the_remade } give_nickname = nick_domcom_the_remade remove_character_flag = domcom_restore_nick_the_remade }
        else_if = { limit = { has_character_flag = domcom_restore_nick_the_unmanned } give_nickname = nick_domcom_the_unmanned remove_character_flag = domcom_restore_nick_the_unmanned }
        else_if = { limit = { has_character_flag = domcom_restore_nick_the_softened } give_nickname = nick_domcom_the_softened remove_character_flag = domcom_restore_nick_the_softened }
        else_if = { limit = { has_character_flag = domcom_restore_nick_dynasty_slave } give_nickname = nick_domcom_dynasty_slave remove_character_flag = domcom_restore_nick_dynasty_slave }
        else_if = { limit = { has_character_flag = domcom_restore_nick_personal_slave } give_nickname = nick_domcom_personal_slave remove_character_flag = domcom_restore_nick_personal_slave }
        else_if = {
            limit = {
                NOT = { has_any_nickname = yes }
                exists = dynasty
                dynasty = { has_dynasty_modifier = strong_blood }
                has_trait = intellect_good
                has_trait = beauty_good
                has_trait = physique_good
                OR = {
                    has_trait = intellect_good_3
                    has_trait = beauty_good_3
                    has_trait = physique_good_3
                }
                has_variable = domcom_cuck_xp
                var:domcom_cuck_xp = 0
            }
            give_nickname = nick_the_blood_motherfather
        }
        if = { limit = { has_character_flag = domcom_displaced_unknown_nickname } remove_character_flag = domcom_displaced_unknown_nickname }
        remove_character_flag = domcom_cuck_nickname_removed_by_repair
    }
}

domcom_award_cucked_nickname_effect = {
    if = {
        limit = {
            domcom_deserves_cucked_nickname_trigger = yes
            NOT = { has_character_flag = domcom_feminized }
            NOT = { has_trait = domcom_feminized_trait }
            NOT = { has_nickname = nick_domcom_the_cucked }
        }
        domcom_mark_displaced_nickname_before_cuck_effect = yes
        give_nickname = nick_domcom_the_cucked
    }
}

# ============================================================================
# v2.4.3 WORLD OUTCOMES / AI TERMINAL DIAGNOSTICS
# ============================================================================
domcom_record_terminal_outcome_effect = {
    set_variable = { name = domcom_terminal_outcome value = $OUTCOME$ }
    if = {
        limit = { exists = scope:domcom_collapse_patron }
        set_variable = { name = domcom_terminal_outcome_patron value = scope:domcom_collapse_patron }
    }
    if = {
        limit = { NOT = { is_target_in_global_variable_list = { name = domcom_all_terminal_outcomes target = this } } }
        add_to_global_variable_list = { name = domcom_all_terminal_outcomes target = this }
    }
}

domcom_ensure_ai_terminal_counters_effect = {
    if = { limit = { NOT = { has_global_variable = domcom_ai_terminal_decisions_v243 } } set_global_variable = { name = domcom_ai_terminal_decisions_v243 value = 0 } }
    if = { limit = { NOT = { has_global_variable = domcom_ai_feminize_eligible_v243 } } set_global_variable = { name = domcom_ai_feminize_eligible_v243 value = 0 } }
    if = { limit = { NOT = { has_global_variable = domcom_ai_feminize_success_v243 } } set_global_variable = { name = domcom_ai_feminize_success_v243 value = 0 } }
}

# One-time backfill makes the page useful immediately on existing saves. It reconstructs only outcomes
# that are still visible on living characters; the diagnostic counters intentionally start at 0 in v2.4.3.
domcom_migrate_world_outcomes_v243_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_world_outcomes_migrated_v243 } }
        domcom_ensure_ai_terminal_counters_effect = yes
        every_living_character = {
            if = {
                limit = { has_character_flag = domcom_feminized has_variable = domcom_feminized_by }
                var:domcom_feminized_by = { save_scope_as = domcom_collapse_patron }
                domcom_record_terminal_outcome_effect = { OUTCOME = flag:feminized }
            }
            else_if = {
                limit = { has_character_flag = domcom_household_final has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_collapse_patron }
                domcom_record_terminal_outcome_effect = { OUTCOME = flag:household }
            }
            else_if = {
                limit = { has_character_flag = domcom_absolute_devotion has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_collapse_patron }
                domcom_record_terminal_outcome_effect = { OUTCOME = flag:devotion }
            }
            else_if = {
                limit = { has_character_flag = domcom_bound_ruler has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_collapse_patron }
                domcom_record_terminal_outcome_effect = { OUTCOME = flag:bound_ruler }
            }
            else_if = {
                limit = { has_character_flag = domcom_collapse_resolved has_variable = domcom_patron }
                var:domcom_patron = { save_scope_as = domcom_collapse_patron }
                domcom_record_terminal_outcome_effect = { OUTCOME = flag:surrendered }
            }
        }
        set_global_variable = domcom_world_outcomes_migrated_v243
    }
}

domcom_prepare_world_outcomes_roster_effect = {
    domcom_migrate_world_outcomes_v243_once_effect = yes
    save_scope_as = domcom_outcomes_viewer
    clear_variable_list = domcom_ui_outcomes_raw
    clear_variable_list = domcom_ui_outcomes
    clear_variable_list = domcom_ui_outcomes_page_list
    set_variable = { name = domcom_ui_outcomes_count value = 0 }
    if = { limit = { NOT = { has_variable = domcom_ui_outcomes_sort_mode } } set_variable = { name = domcom_ui_outcomes_sort_mode value = flag:outcome } }
    if = { limit = { NOT = { has_variable = domcom_ui_outcomes_sort_direction } } set_variable = { name = domcom_ui_outcomes_sort_direction value = flag:descending } }

    if = {
        limit = { has_global_variable_list = domcom_all_terminal_outcomes }
        every_in_global_list = {
            variable = domcom_all_terminal_outcomes
            limit = { is_alive = yes has_variable = domcom_terminal_outcome }
            save_temporary_scope_as = domcom_outcome_subject
            # Cache the responsible Patron's current living Absolute Submission count for World Outcomes
            # sorting/display. This is computed only while this diagnostic page is opened.
            remove_variable = domcom_ui_outcome_patron_slave_count
            if = {
                limit = { has_variable = domcom_terminal_outcome_patron var:domcom_terminal_outcome_patron = { is_alive = yes } }
                var:domcom_terminal_outcome_patron = {
                    save_scope_as = domcom_outcome_patron_for_count
                    set_variable = { name = domcom_ui_current_slave_count value = 0 }
                    if = {
                        limit = { has_variable_list = domcom_pet_registry }
                        every_in_list = {
                            variable = domcom_pet_registry
                            limit = { is_alive = yes has_character_flag = domcom_pet has_variable = domcom_pet_patron var:domcom_pet_patron = scope:domcom_outcome_patron_for_count }
                            scope:domcom_outcome_patron_for_count = { change_variable = { name = domcom_ui_current_slave_count add = 1 } }
                        }
                    }
                }
                set_variable = { name = domcom_ui_outcome_patron_slave_count value = scope:domcom_outcome_patron_for_count.var:domcom_ui_current_slave_count }
            }
            scope:domcom_outcomes_viewer = {
                add_to_variable_list = { name = domcom_ui_outcomes_raw target = scope:domcom_outcome_subject }
                change_variable = { name = domcom_ui_outcomes_count add = 1 }
            }
        }
    }
    domcom_rebuild_world_outcomes_roster_effect = yes
}

domcom_rebuild_world_outcomes_roster_effect = {
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_outcomes
    if = {
        limit = { has_variable_list = domcom_ui_outcomes_raw }
        ordered_in_list = {
            variable = domcom_ui_outcomes_raw
            order_by = domcom_world_outcome_sort_value
            max = 100000
            check_range_bounds = no
            save_temporary_scope_as = domcom_sorted_outcome
            scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_outcomes target = scope:domcom_sorted_outcome } }
        }
    }
    set_variable = { name = domcom_ui_outcomes_page value = 0 }
    domcom_build_world_outcomes_page_effect = yes
}

domcom_build_world_outcomes_page_effect = {
    # v2.5.1: page navigation calls this effect directly, so recreate the Patron scope on every page.
    save_scope_as = domcom_ui_patron
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_outcomes_page } } set_variable = { name = domcom_ui_outcomes_page value = 0 } }
    clear_variable_list = domcom_ui_outcomes_page_list
    set_variable = { name = domcom_ui_outcomes_total value = 0 }
    set_variable = { name = domcom_ui_outcomes_last_page value = 0 }
    set_variable = { name = domcom_ui_outcomes_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_outcomes }
        every_in_list = {
            variable = domcom_ui_outcomes
            prev = {
                if = {
                    limit = { var:domcom_ui_outcomes_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_outcomes_last_page add = 1 }
                    set_variable = { name = domcom_ui_outcomes_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_outcomes_page_fill add = 1 }
                change_variable = { name = domcom_ui_outcomes_total add = 1 }
            }
        }
    }
    if = { limit = { var:domcom_ui_outcomes_page < 0 } set_variable = { name = domcom_ui_outcomes_page value = 0 } }
    if = { limit = { var:domcom_ui_outcomes_page > var:domcom_ui_outcomes_last_page } set_variable = { name = domcom_ui_outcomes_page value = var:domcom_ui_outcomes_last_page } }

    set_variable = { name = domcom_ui_outcomes_first value = var:domcom_ui_outcomes_page }
    change_variable = { name = domcom_ui_outcomes_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_outcomes_stop value = var:domcom_ui_outcomes_first }
    change_variable = { name = domcom_ui_outcomes_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_outcomes_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_outcomes }
        every_in_list = {
            variable = domcom_ui_outcomes
            save_temporary_scope_as = domcom_outcome_page_candidate
            scope:domcom_ui_patron = {
                if = {
                    limit = { var:domcom_ui_outcomes_index >= var:domcom_ui_outcomes_first var:domcom_ui_outcomes_index < var:domcom_ui_outcomes_stop }
                    add_to_variable_list = { name = domcom_ui_outcomes_page_list target = scope:domcom_outcome_page_candidate }
                }
                change_variable = { name = domcom_ui_outcomes_index add = 1 }
            }
        }
    }
    set_variable = { name = domcom_ui_outcomes_display_page value = var:domcom_ui_outcomes_page }
    change_variable = { name = domcom_ui_outcomes_display_page add = 1 }
    set_variable = { name = domcom_ui_outcomes_display_last value = var:domcom_ui_outcomes_last_page }
    change_variable = { name = domcom_ui_outcomes_display_last add = 1 }
    set_variable = { name = domcom_ui_outcomes_display_first value = var:domcom_ui_outcomes_first }
    if = { limit = { var:domcom_ui_outcomes_total > 0 } change_variable = { name = domcom_ui_outcomes_display_first add = 1 } }
    set_variable = { name = domcom_ui_outcomes_display_stop value = var:domcom_ui_outcomes_stop }
    if = { limit = { var:domcom_ui_outcomes_display_stop > var:domcom_ui_outcomes_total } set_variable = { name = domcom_ui_outcomes_display_stop value = var:domcom_ui_outcomes_total } }
}

domcom_monthly_dominion_upkeep_effect = {
    domcom_devotion_monthly_patron_effect = yes
    domcom_repair_pet_registry_for_patron_effect = yes
    domcom_repair_protected_intimates_effect = yes

    # Recover newly-created human-player evidence (vanilla Lover/Soulmate links and biological children)
    # without waiting for the Ledger to be opened. This traverses only the Patron's intimate/child graph,
    # not the living world.
    domcom_fast_recover_records_effect = yes
    domcom_enforce_communion_for_patron_effect = yes
    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = { is_alive = yes has_character_flag = domcom_cucked }
            domcom_refresh_cuck_reputation_effect = yes
        }
    }
}

domcom_order_cucked_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_sort_total_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_sort_total_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}

domcom_order_cucked_prize_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = { value = domcom_sort_prize_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_cucked_raw order_by = domcom_sort_prize_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_cucked_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_cucked_count add = 1 } } }
    }
}

domcom_order_owned_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_sort_total_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_sort_total_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}

domcom_order_owned_prize_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = { value = domcom_sort_prize_value multiply = -1 } limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_owned_raw order_by = domcom_sort_prize_value limit = { domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_owned_subjects target = scope:domcom_sorted_item } change_variable = { name = domcom_ui_filtered_owned_count add = 1 } } }
    }
}

domcom_order_prospects_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = domcom_sort_total_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = domcom_sort_total_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}

domcom_order_prospects_prize_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = { value = domcom_sort_prize_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_prospects_raw order_by = domcom_sort_prize_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_prospects target = scope:domcom_sorted_item } } }
    }
}

domcom_order_blood_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = domcom_sort_total_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = domcom_sort_total_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}

domcom_order_blood_prize_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = { value = domcom_sort_prize_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_blood_raw order_by = domcom_sort_prize_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_blood_children target = scope:domcom_sorted_item } } }
    }
}

domcom_rebuild_cucked_total_effect = { domcom_order_cucked_total_effect = yes }

domcom_rebuild_cucked_prize_effect = { domcom_order_cucked_prize_effect = yes }

domcom_rebuild_owned_total_effect = { domcom_order_owned_total_effect = yes }

domcom_rebuild_owned_prize_effect = { domcom_order_owned_prize_effect = yes }


# v2.4.3 stress safety rail. Positive Dominion stress stops once a character is already at 150 stress.
# Negative values are genuine personality-based stress relief and remain allowed at any stress level;
# only positive additions are suppressed by the safety rail.
domcom_dominion_success_stress_effect = {
    if = {
        limit = { domcom_dominion_success_stress_value <= 0 }
        add_stress = domcom_dominion_success_stress_value
    }
    else_if = {
        limit = { stress < 150 }
        add_stress = domcom_dominion_success_stress_value
    }
}

domcom_dominion_rejection_stress_effect = {
    if = { limit = { stress < 150 } add_stress = domcom_dominion_rejection_stress_value }
}


domcom_repair_failed_collapses_effect = {
    save_scope_as = domcom_repair_patron
    every_living_character = {
        limit = {
            OR = {
                is_landed = yes
                is_landless_adventurer = yes
                any_held_title = { is_noble_family_title = yes }
                any_held_title = { is_nomad_title = yes }
            }
            OR = {
                AND = {
                    has_character_flag = domcom_collapse_seizure_failed
                    has_variable = domcom_patron
                    var:domcom_patron = scope:domcom_repair_patron
                }
                AND = {
                    has_character_flag = domcom_collapse_resolved
                    has_variable = domcom_patron
                    var:domcom_patron = scope:domcom_repair_patron
                }
            }
        }

        if = {
            limit = {
                has_character_flag = domcom_collapse_seizure_failed
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_repair_patron
            }
            remove_character_flag = domcom_collapse_resolved
            remove_character_flag = domcom_collapse_seizure_failed
            if = { limit = { has_character_modifier = domcom_final_submission_modifier } remove_character_modifier = domcom_final_submission_modifier }
            # Retry immediately so a stranded Noble Family/Yurt title in an existing save does not need
            # to wait for a later Dominion pulse before the repaired Final Collapse is offered.
            domcom_check_final_collapse_effect = yes
        }
        else_if = {
            limit = {
                has_character_flag = domcom_collapse_resolved
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_repair_patron
            }
            remove_character_flag = domcom_collapse_resolved
            if = { limit = { has_character_modifier = domcom_final_submission_modifier } remove_character_modifier = domcom_final_submission_modifier }
        }
    }
}


# Local invariant repair for a single character. Unlike the Ledger audit this does not scan the world.
# It exists specifically so secondary sex hooks cannot leave a self-cuck record behind in the same tick.
domcom_purge_impossible_self_cuck_effect = {
    save_scope_as = domcom_self_cuck_subject

    if = { limit = { has_variable = domcom_cuck_origin_patron var:domcom_cuck_origin_patron = scope:domcom_self_cuck_subject } remove_variable = domcom_cuck_origin_patron }
    if = { limit = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_self_cuck_subject } remove_variable = domcom_cuck_patron }
    if = { limit = { has_variable = domcom_cuck_registry_patron var:domcom_cuck_registry_patron = scope:domcom_self_cuck_subject } remove_variable = domcom_cuck_registry_patron }
    if = {
        limit = { has_variable = domcom_patron var:domcom_patron = scope:domcom_self_cuck_subject }
        remove_variable = domcom_patron
        remove_character_flag = domcom_owned_cuck
        remove_character_modifier = domcom_owned_modifier
    }
    if = { limit = { has_variable_list = domcom_cuck_patrons } remove_list_variable = { name = domcom_cuck_patrons target = scope:domcom_self_cuck_subject } }
    if = { limit = { has_variable_list = domcom_sex_evidence_patrons } remove_list_variable = { name = domcom_sex_evidence_patrons target = scope:domcom_self_cuck_subject } }
    if = { limit = { has_variable_list = domcom_betrayal_evidence_patrons } remove_list_variable = { name = domcom_betrayal_evidence_patrons target = scope:domcom_self_cuck_subject } }
    if = { limit = { has_variable_list = domcom_cucked_registry } remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_self_cuck_subject } }

    # Decide from actual surviving non-self evidence rather than list-container existence; an emptied
    # variable list may continue to exist in the save after its last entry is removed.
    remove_character_flag = domcom_self_cuck_has_valid_external_patron
    if = { limit = { has_variable = domcom_cuck_origin_patron NOT = { var:domcom_cuck_origin_patron = scope:domcom_self_cuck_subject } } add_character_flag = domcom_self_cuck_has_valid_external_patron }
    if = { limit = { has_variable = domcom_cuck_patron NOT = { var:domcom_cuck_patron = scope:domcom_self_cuck_subject } } add_character_flag = domcom_self_cuck_has_valid_external_patron }
    if = { limit = { has_variable = domcom_cuck_registry_patron NOT = { var:domcom_cuck_registry_patron = scope:domcom_self_cuck_subject } } add_character_flag = domcom_self_cuck_has_valid_external_patron }
    if = { limit = { has_variable = domcom_patron NOT = { var:domcom_patron = scope:domcom_self_cuck_subject } } add_character_flag = domcom_self_cuck_has_valid_external_patron }
    if = {
        limit = { has_variable_list = domcom_cuck_patrons }
        every_in_list = {
            variable = domcom_cuck_patrons
            limit = { NOT = { this = scope:domcom_self_cuck_subject } }
            scope:domcom_self_cuck_subject = { add_character_flag = domcom_self_cuck_has_valid_external_patron }
        }
    }
    if = {
        limit = { has_variable_list = domcom_sex_evidence_patrons }
        every_in_list = {
            variable = domcom_sex_evidence_patrons
            limit = { NOT = { this = scope:domcom_self_cuck_subject } }
            scope:domcom_self_cuck_subject = { add_character_flag = domcom_self_cuck_has_valid_external_patron }
        }
    }

    # If there is no surviving non-self Patron/evidence, a public Cucked state created by the bad hook
    # has no legitimate provenance and can be removed immediately. Genuine third-party records survive.
    if = {
        limit = {
            has_character_flag = domcom_cucked
            NOT = { has_character_flag = domcom_self_cuck_has_valid_external_patron }
        }
        if = {
            limit = { has_nickname = nick_domcom_the_cucked }
            add_character_flag = domcom_cuck_nickname_removed_by_repair
            remove_nickname = yes
        }
        remove_character_flag = domcom_cucked
        remove_character_flag = domcom_cuck_registry_added
        remove_character_flag = domcom_global_cuck_registry_added
        remove_character_modifier = domcom_cucked_modifier
        if = { limit = { has_trait = domcom_cucked_trait } remove_trait = domcom_cucked_trait }
        remove_character_modifier = domcom_humiliated_stage_modifier
        remove_character_modifier = domcom_submissive_stage_modifier
        remove_character_modifier = domcom_broken_stage_modifier
        remove_character_modifier = domcom_abject_stage_modifier
        remove_character_modifier = domcom_final_submission_modifier
        set_variable = { name = domcom_cuck_xp value = 0 }
        if = {
            limit = { has_character_flag = domcom_cuck_nickname_removed_by_repair }
            domcom_restore_displaced_nickname_after_bad_cuck_effect = yes
        }
    }
    remove_character_flag = domcom_self_cuck_has_valid_external_patron
}

# Remove impossible provenance where the recorded "Patron" is the subject themself or one of the
# subject's current lawful spouses/concubines/consorts. Genuine outside Patrons/evidence are retained.
domcom_repair_lawful_partner_cuck_provenance_effect = {
    save_scope_as = domcom_lawful_repair_subject
    domcom_purge_impossible_self_cuck_effect = yes

    every_consort = {
        save_temporary_scope_as = domcom_invalid_lawful_patron
        scope:domcom_lawful_repair_subject = {
            if = { limit = { has_variable = domcom_cuck_origin_patron var:domcom_cuck_origin_patron = scope:domcom_invalid_lawful_patron } remove_variable = domcom_cuck_origin_patron }
            if = { limit = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_invalid_lawful_patron } remove_variable = domcom_cuck_patron }
            if = { limit = { has_variable = domcom_cuck_registry_patron var:domcom_cuck_registry_patron = scope:domcom_invalid_lawful_patron } remove_variable = domcom_cuck_registry_patron }
            if = { limit = { has_variable_list = domcom_cuck_patrons } remove_list_variable = { name = domcom_cuck_patrons target = scope:domcom_invalid_lawful_patron } }
            if = { limit = { has_variable_list = domcom_sex_evidence_patrons } remove_list_variable = { name = domcom_sex_evidence_patrons target = scope:domcom_invalid_lawful_patron } }
            if = { limit = { has_variable_list = domcom_betrayal_evidence_patrons } remove_list_variable = { name = domcom_betrayal_evidence_patrons target = scope:domcom_invalid_lawful_patron } }
        }
        # Remove the bad subject from that lawful partner's own history/registry as well.
        if = { limit = { has_variable_list = domcom_cucked_registry } remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_lawful_repair_subject } }
        if = { limit = { has_variable_list = domcom_sex_cuck_targets } remove_list_variable = { name = domcom_sex_cuck_targets target = scope:domcom_lawful_repair_subject } }
    }

    # Re-use the proven external-evidence test after unlawful provenance is stripped.
    domcom_purge_impossible_self_cuck_effect = yes
    remove_character_flag = domcom_lawful_repair_has_external
    if = { limit = { has_variable = domcom_cuck_origin_patron NOT = { var:domcom_cuck_origin_patron = scope:domcom_lawful_repair_subject } var:domcom_cuck_origin_patron = { NOT = { is_consort_of = scope:domcom_lawful_repair_subject } } } add_character_flag = domcom_lawful_repair_has_external }
    if = { limit = { has_variable = domcom_cuck_patron NOT = { var:domcom_cuck_patron = scope:domcom_lawful_repair_subject } var:domcom_cuck_patron = { NOT = { is_consort_of = scope:domcom_lawful_repair_subject } } } add_character_flag = domcom_lawful_repair_has_external }
    if = { limit = { has_variable_list = domcom_cuck_patrons } every_in_list = { variable = domcom_cuck_patrons limit = { NOT = { this = scope:domcom_lawful_repair_subject } NOT = { is_consort_of = scope:domcom_lawful_repair_subject } } scope:domcom_lawful_repair_subject = { add_character_flag = domcom_lawful_repair_has_external } } }
    if = { limit = { has_variable_list = domcom_sex_evidence_patrons } every_in_list = { variable = domcom_sex_evidence_patrons limit = { NOT = { this = scope:domcom_lawful_repair_subject } NOT = { is_consort_of = scope:domcom_lawful_repair_subject } } scope:domcom_lawful_repair_subject = { add_character_flag = domcom_lawful_repair_has_external } } }

    if = {
        limit = { has_character_flag = domcom_cucked NOT = { has_character_flag = domcom_lawful_repair_has_external } }
        if = {
            limit = { has_nickname = nick_domcom_the_cucked }
            add_character_flag = domcom_cuck_nickname_removed_by_repair
            remove_nickname = yes
        }
        remove_character_flag = domcom_cucked
        remove_character_flag = domcom_cuck_registry_added
        remove_character_flag = domcom_global_cuck_registry_added
        remove_character_modifier = domcom_cucked_modifier
        if = { limit = { has_trait = domcom_cucked_trait } remove_trait = domcom_cucked_trait }
        remove_character_modifier = domcom_humiliated_stage_modifier
        remove_character_modifier = domcom_submissive_stage_modifier
        remove_character_modifier = domcom_broken_stage_modifier
        remove_character_modifier = domcom_abject_stage_modifier
        remove_character_modifier = domcom_final_submission_modifier
        set_variable = { name = domcom_cuck_xp value = 0 }
        if = {
            limit = { has_character_flag = domcom_cuck_nickname_removed_by_repair }
            domcom_restore_displaced_nickname_after_bad_cuck_effect = yes
        }
    }
    remove_character_flag = domcom_lawful_repair_has_external
}

# v2.4.2 save repair.  2.4.1 could already have removed an invalid Cucked nickname, leaving the
# character with no nickname and a zeroed cuck XP variable.  Restore Blood-Father/Blood-Mother only when
# the player also matches the actual Strengthen Bloodline achievement profile.  This is deliberately a
# one-time legacy bridge; future records use domcom_restore_nick_blood_motherfather instead.
domcom_migrate_nickname_repair_v242_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_nickname_repair_v242 } }
        every_player = {
            if = {
                limit = {
                    NOT = { has_any_nickname = yes }
                    NOT = { has_character_flag = domcom_cucked }
                    exists = dynasty
                    dynasty = { has_dynasty_modifier = strong_blood }
                    has_trait = intellect_good
                    has_trait = beauty_good
                    has_trait = physique_good
                    OR = {
                        has_trait = intellect_good_3
                        has_trait = beauty_good_3
                        has_trait = physique_good_3
                    }
                    has_variable = domcom_cuck_xp
                    var:domcom_cuck_xp = 0
                }
                give_nickname = nick_the_blood_motherfather
            }
        }
        set_global_variable = domcom_nickname_repair_v242
    }
}

# scope:domcom_intimacy_partner and scope:domcom_intimacy_patron are saved by

domcom_intimacy_resolve_effect = {
    # 2.5.1 safety net: even if a future AI path invokes Invite to Bed directly, Dominion-generated sex
    # with a human player's lawful partner is intercepted before had_sex_with_effect.
    if = {
        limit = {
            scope:domcom_intimacy_patron = { is_ai = yes }
            scope:domcom_intimacy_partner = {
                NOT = { is_consort_of = scope:domcom_intimacy_patron }
                any_consort = { is_alive = yes age >= 18 is_ai = no }
            }
        }
        scope:domcom_intimacy_patron = {
            save_scope_as = domcom_tantalize_patron
            add_character_flag = domcom_intimacy_intercepted_by_guard
        }
        scope:domcom_intimacy_partner = { domcom_queue_ai_courtship_against_player_effect = yes }
    }
    else = {
    # Direct Dominion intimacy is a positive Mastery experience. Keep the optional Carnalitas hook from
    # double-scoring the same had_sex_with_effect call.
    scope:domcom_intimacy_patron = { add_character_flag = domcom_mastery_direct_sex_guard }
    scope:domcom_intimacy_partner = { add_character_flag = domcom_mastery_direct_sex_guard }

    scope:domcom_intimacy_patron = {
        had_sex_with_effect = {
            CHARACTER = scope:domcom_intimacy_partner
            PREGNANCY_CHANCE = pregnancy_chance
        }
    }

    scope:domcom_intimacy_patron = {
        remove_character_flag = domcom_mastery_direct_sex_guard
        if = { limit = { is_male = yes age >= 18 } domcom_endowment_mastery_direct_positive_sex_effect = yes }
        if = { limit = { is_female = yes age >= 18 } domcom_breast_mastery_direct_positive_sex_effect = yes }
    }
    scope:domcom_intimacy_partner = {
        remove_character_flag = domcom_mastery_direct_sex_guard
        if = { limit = { is_male = yes age >= 18 } domcom_endowment_mastery_direct_positive_sex_effect = yes }
        if = { limit = { is_female = yes age >= 18 } domcom_breast_mastery_direct_positive_sex_effect = yes }
    }

    # Invite-to-Bed with one's own spouse/concubine is ordinary household intimacy, not evidence.
    # had_sex_with_effect can itself fan out through third-party on_actions, so clean the two participants
    # locally after it fires and do not invoke Dominion's direct betrayal recorder at all.
    if = {
        limit = { scope:domcom_intimacy_partner = { is_consort_of = scope:domcom_intimacy_patron } }
        scope:domcom_intimacy_patron = { domcom_repair_lawful_partner_cuck_provenance_effect = yes }
        scope:domcom_intimacy_partner = { domcom_repair_lawful_partner_cuck_provenance_effect = yes }
    }
    else = {
        scope:domcom_intimacy_patron = { save_scope_as = domcom_direct_sex_patron }
        scope:domcom_intimacy_partner = { domcom_record_direct_dominion_sex_effect = yes }
    }

    # Cuck Experience accrues to a genuine outside spouse whether or not anyone is caught.
    if = {
        limit = {
            exists = scope:domcom_intimacy_cuckold
            scope:domcom_intimacy_cuckold = { NOT = { this = scope:domcom_intimacy_patron } }
            scope:domcom_intimacy_partner = { NOT = { is_consort_of = scope:domcom_intimacy_patron } }
        }
        scope:domcom_intimacy_cuckold = {
            if = { limit = { NOT = { has_variable = domcom_cuck_xp } } set_variable = { name = domcom_cuck_xp value = 100 } }
            change_variable = { name = domcom_cuck_xp add = scope:domcom_intimacy_xp }
            domcom_register_cuck_generic_effect = yes
        }
    }
    scope:domcom_intimacy_partner = {
        add_opinion = { target = scope:domcom_intimacy_patron modifier = domcom_intimacy_shared_opinion }
        if = {
            limit = {
                has_variable = domcom_obedience_patron
                var:domcom_obedience_patron = scope:domcom_intimacy_patron
                has_variable = domcom_obedience
                NOT = { has_character_flag = domcom_pet }
            }
            change_variable = { name = domcom_obedience add = 25 }
            if = { limit = { var:domcom_obedience > 1000 } set_variable = { name = domcom_obedience value = 1000 } }
            domcom_refresh_obedience_stage_effect = yes
        }
    }

    }
}

domcom_intimacy_undetected_effect = {
    # Nobody catches the pair. The Patron receives a one-year experience-style reward rather than
    # permanently farmable raw skill points.
    scope:domcom_intimacy_patron = {
        if = {
            limit = { scope:domcom_intimacy_style = flag:discreet }
            add_character_modifier = { modifier = domcom_intimacy_discreet_modifier years = 1 }
            add_dread = 2
        }
        else_if = {
            limit = { scope:domcom_intimacy_style = flag:open }
            add_character_modifier = { modifier = domcom_intimacy_open_modifier years = 1 }
            add_dread = 5
        }
        else_if = {
            limit = { scope:domcom_intimacy_style = flag:brazen }
            add_character_modifier = { modifier = domcom_intimacy_brazen_modifier years = 1 }
            add_dread = 10
        }
        domcom_dominion_success_stress_effect = yes
    }
}

domcom_intimacy_discovered_effect = {
    scope:domcom_intimacy_patron = {
        add_prestige = scope:domcom_intimacy_prestige_loss
    }
    scope:domcom_intimacy_partner = { if = { limit = { stress < 150 } add_stress = domcom_intimacy_discovered_stress_value } }

    if = {
        limit = {
            exists = scope:domcom_intimacy_cuckold
            scope:domcom_intimacy_partner = { NOT = { is_consort_of = scope:domcom_intimacy_patron } }
            scope:domcom_intimacy_cuckold = {
                domcom_intimacy_cuckold_submitted_to_patron_trigger = { PATRON = scope:domcom_intimacy_patron }
            }
        }
        # Final Submission means the household has already yielded to this Patron. Exposure can still
        # cost prestige and create gossip, but the submitted cuck no longer gets a fresh confrontation
        # roll and cannot imprison either participant for the same relationship.
        # There is no confrontation to "win" here. The ordinary discovery costs above still apply,
        # but do not hand out the Prevailed-When-Confronted reward or a repeatable Dread farm.
        scope:domcom_intimacy_patron = {
            trigger_event = { id = domcom_intimacy.0004 days = 1 }
        }
    }
    else_if = {
        limit = {
            exists = scope:domcom_intimacy_cuckold
            scope:domcom_intimacy_partner = { NOT = { is_consort_of = scope:domcom_intimacy_patron } }
        }
        scope:domcom_intimacy_cuckold = {
            add_opinion = { target = scope:domcom_intimacy_patron modifier = domcom_intimacy_discovered_partner_opinion }
            every_close_family_member = {
                limit = { is_alive = yes }
                add_opinion = { target = scope:domcom_intimacy_patron modifier = domcom_intimacy_discovered_court_opinion }
            }

            random = {
                chance = domcom_intimacy_escape_chance_value
                add_character_flag = domcom_intimacy_patron_prevailed_roll
            }
            if = {
                limit = { has_character_flag = domcom_intimacy_patron_prevailed_roll }
                remove_character_flag = domcom_intimacy_patron_prevailed_roll
                # Seen, but the Patron is too dangerous/clever to corner.
                scope:domcom_intimacy_patron = {
                    add_character_modifier = { modifier = domcom_intimacy_prevailed_modifier years = 1 }
                    add_dread = 5
                }
                if = {
                    limit = { has_variable = domcom_cuck_xp }
                    change_variable = { name = domcom_cuck_xp add = 50 }
                    domcom_refresh_cuck_stage_effect = yes
                }
                scope:domcom_intimacy_patron = { trigger_event = { id = domcom_intimacy.0002 days = 1 } }
            }
            else = {
                # The spouse wins the confrontation. They gain the confidence and intimidation reward
                # that the Patron would have gained by getting away cleanly; imprisonment still requires
                # authority.
                add_character_modifier = { modifier = domcom_intimacy_enforcer_modifier years = 1 }
                if = { limit = { scope:domcom_intimacy_style = flag:discreet } add_dread = 2 }
                else_if = { limit = { scope:domcom_intimacy_style = flag:open } add_dread = 5 }
                else_if = { limit = { scope:domcom_intimacy_style = flag:brazen } add_dread = 10 }
                scope:domcom_intimacy_patron = {
                    domcom_dominion_rejection_stress_effect = yes
                    add_character_modifier = { modifier = domcom_intimacy_cornered_modifier years = 1 }
                }

                # Partner imprisonment chance scales with how brazen the choice was.
                if = {
                    limit = {
                        scope:domcom_intimacy_partner = { OR = { is_courtier_of = scope:domcom_intimacy_cuckold is_vassal_of = scope:domcom_intimacy_cuckold } }
                    }
                    if = { limit = { scope:domcom_intimacy_style = flag:discreet } random = { chance = 25 imprison = { target = scope:domcom_intimacy_partner type = house_arrest } } }
                    else_if = { limit = { scope:domcom_intimacy_style = flag:open } random = { chance = 50 imprison = { target = scope:domcom_intimacy_partner type = house_arrest } } }
                    else_if = { limit = { scope:domcom_intimacy_style = flag:brazen } random = { chance = 80 imprison = { target = scope:domcom_intimacy_partner type = house_arrest } } }
                }

                # The Patron can only be jailed if the spouse actually rules over them.
                if = {
                    limit = {
                        scope:domcom_intimacy_patron = { OR = { is_courtier_of = scope:domcom_intimacy_cuckold is_vassal_of = scope:domcom_intimacy_cuckold } }
                    }
                    if = { limit = { scope:domcom_intimacy_style = flag:discreet } random = { chance = 10 imprison = { target = scope:domcom_intimacy_patron type = house_arrest } } }
                    else_if = { limit = { scope:domcom_intimacy_style = flag:open } random = { chance = 25 imprison = { target = scope:domcom_intimacy_patron type = house_arrest } } }
                    else_if = { limit = { scope:domcom_intimacy_style = flag:brazen } random = { chance = 50 imprison = { target = scope:domcom_intimacy_patron type = house_arrest } } }
                }

                scope:domcom_intimacy_patron = { trigger_event = { id = domcom_intimacy.0003 days = 1 } }
            }
        }
    }
    else = {
        # No spouse to confront the pair; discovery is reputational, but there is nobody with standing to
        # corner the Patron.
        scope:domcom_intimacy_patron = {
            add_character_modifier = { modifier = domcom_intimacy_prevailed_modifier years = 1 }
            add_dread = 3
            trigger_event = { id = domcom_intimacy.0002 days = 1 }
        }
    }
}


domcom_order_world_rank_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = domcom_sort_rank_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = domcom_sort_rank_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_endowment_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = domcom_length_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = domcom_length_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_xp_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = domcom_sort_xp_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = domcom_sort_xp_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_diplomacy_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = diplomacy multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = diplomacy max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_martial_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = martial multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = martial max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_stewardship_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = stewardship multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = stewardship max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_intrigue_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = intrigue multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = intrigue max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_learning_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = learning multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = learning max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_prowess_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = prowess multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = prowess max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_total_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = domcom_sort_total_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = domcom_sort_total_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}

domcom_order_world_prize_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = { value = domcom_sort_prize_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_world_cucks_raw order_by = domcom_sort_prize_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_world_cuck_item scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_world_cucks target = scope:domcom_world_cuck_item } } }
    }
}


# ENDOWMENT REGISTRY — lazy world index. The one-time backfill exists for saves created before v1.6;
# all newly initialized adult male profiles add themselves to domcom_all_endowments automatically.
# Crash-safe registry view: never scans every living character from a button click.
domcom_prepare_endowments_roster_safe_effect = {
    # Default to the physical men's registry. The women's view uses the same paged list container but
    # its own global preference index and sort modes.
    if = { limit = { NOT = { has_variable = domcom_ui_endowment_view } } set_variable = { name = domcom_ui_endowment_view value = flag:men } }
    if = {
        limit = { var:domcom_ui_endowment_view = flag:women }
        domcom_prepare_endowment_preferences_roster_safe_effect = yes
    }
    else_if = {
        limit = { var:domcom_ui_endowment_view = flag:breasts }
        domcom_prepare_breast_profiles_roster_safe_effect = yes
    }
    else_if = {
        limit = { var:domcom_ui_endowment_view = flag:breast_prefs }
        domcom_prepare_breast_preferences_roster_safe_effect = yes
    }
    else = {
        domcom_clear_ui_raw_roster_caches_effect = yes
        save_scope_as = domcom_ui_patron
        clear_variable_list = domcom_ui_endowments_raw
        clear_variable_list = domcom_ui_endowments
        clear_variable_list = domcom_ui_endowments_page_list
        set_variable = { name = domcom_ui_endowments_count value = 0 }
        if = {
            limit = { has_global_variable_list = domcom_all_endowments }
            every_in_global_list = {
                variable = domcom_all_endowments
                limit = { is_alive = yes is_male = yes age >= 18 has_variable = domcom_length_tenths has_variable = domcom_girth_tenths }
                save_temporary_scope_as = domcom_ui_ref
                scope:domcom_ui_patron = {
                    add_to_variable_list = { name = domcom_ui_endowments_raw target = scope:domcom_ui_ref }
                    change_variable = { name = domcom_ui_endowments_count add = 1 }
                }
            }
        }
        if = {
            limit = { OR = { var:domcom_ui_sort_mode = flag:pref_length var:domcom_ui_sort_mode = flag:pref_girth var:domcom_ui_sort_mode = flag:pref_both var:domcom_ui_sort_mode = flag:endowment } }
            set_variable = { name = domcom_ui_sort_mode value = flag:length }
        }
        domcom_rebuild_ui_rosters_effect = yes
    }
}

# Women's preference view. Older saves do one index pass the first time this view is opened; newly
# initialized profiles register themselves in domcom_assign_size_preference_effect.
domcom_prepare_endowment_preferences_roster_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_endowments_raw
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_endowments_page_list
    set_variable = { name = domcom_ui_endowments_count value = 0 }

    if = {
        limit = { NOT = { has_global_variable = domcom_preference_registry_backfilled_v243 } }
        every_living_character = {
            limit = {
                is_female = yes age >= 18 is_attracted_to_men = yes
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
                NOT = { is_target_in_global_variable_list = { name = domcom_all_preference_profiles target = this } }
            }
            add_to_global_variable_list = { name = domcom_all_preference_profiles target = this }
        }
        set_global_variable = domcom_preference_registry_backfilled_v243
    }

    if = {
        limit = { has_global_variable_list = domcom_all_preference_profiles }
        every_in_global_list = {
            variable = domcom_all_preference_profiles
            limit = {
                is_alive = yes is_female = yes age >= 18 is_attracted_to_men = yes
                has_variable = domcom_pref_length_tenths
                has_variable = domcom_pref_girth_tenths
            }
            save_temporary_scope_as = domcom_pref_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_endowments_raw target = scope:domcom_pref_subject }
                change_variable = { name = domcom_ui_endowments_count add = 1 }
            }
        }
    }
    if = {
        limit = { NOR = { var:domcom_ui_sort_mode = flag:pref_length var:domcom_ui_sort_mode = flag:pref_girth var:domcom_ui_sort_mode = flag:pref_both } }
        set_variable = { name = domcom_ui_sort_mode value = flag:pref_length }
    }
    domcom_rebuild_ui_rosters_effect = yes
}


# Breast Profile physical registry. Shares the Endowment page's standard list/pagination container.
domcom_prepare_breast_profiles_roster_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_endowments_raw
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_endowments_page_list
    set_variable = { name = domcom_ui_endowments_count value = 0 }

    if = {
        limit = { NOT = { has_global_variable = domcom_breast_registry_backfilled_v258 } }
        every_living_character = {
            limit = { is_female = yes age >= 18 }
            domcom_assign_breast_profile_effect = yes
        }
        set_global_variable = domcom_breast_registry_backfilled_v258
    }
    if = {
        limit = { has_global_variable_list = domcom_all_breast_profiles }
        every_in_global_list = {
            variable = domcom_all_breast_profiles
            limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_underbust_tenths has_variable = domcom_bust_tenths has_variable = domcom_breast_fullness_tenths }
            save_temporary_scope_as = domcom_breast_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_endowments_raw target = scope:domcom_breast_subject }
                change_variable = { name = domcom_ui_endowments_count add = 1 }
            }
        }
    }
    if = { limit = { NOR = { var:domcom_ui_sort_mode = flag:breast_fullness var:domcom_ui_sort_mode = flag:bust var:domcom_ui_sort_mode = flag:underbust var:domcom_ui_sort_mode = flag:breast_mastery } } set_variable = { name = domcom_ui_sort_mode value = flag:breast_fullness } }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_prepare_breast_preferences_roster_safe_effect = {
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_endowments_raw
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_endowments_page_list
    set_variable = { name = domcom_ui_endowments_count value = 0 }

    if = {
        limit = { NOT = { has_global_variable = domcom_breast_preference_registry_backfilled_v258 } }
        every_living_character = {
            limit = { age >= 18 is_attracted_to_women = yes }
            domcom_assign_breast_preference_effect = yes
        }
        set_global_variable = domcom_breast_preference_registry_backfilled_v258
    }
    if = {
        limit = { has_global_variable_list = domcom_all_breast_preferences }
        every_in_global_list = {
            variable = domcom_all_breast_preferences
            limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_underbust_tenths has_variable = domcom_pref_breast_fullness_tenths }
            save_temporary_scope_as = domcom_breast_pref_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_endowments_raw target = scope:domcom_breast_pref_subject }
                change_variable = { name = domcom_ui_endowments_count add = 1 }
            }
        }
    }
    if = { limit = { NOR = { var:domcom_ui_sort_mode = flag:pref_breast_fullness var:domcom_ui_sort_mode = flag:pref_breast_frame var:domcom_ui_sort_mode = flag:pref_breast_both } } set_variable = { name = domcom_ui_sort_mode value = flag:pref_breast_both } }
    domcom_rebuild_ui_rosters_effect = yes
}

domcom_order_breasts_fullness_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_breast_fullness_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_breast_fullness_value limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_breasts_bust_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_bust_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_bust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_bust_value limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_bust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_breasts_underbust_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_underbust_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_underbust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_underbust_value limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_underbust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_breasts_mastery_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_breast_mastery_value multiply = -1 } limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_breast_mastery_xp domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_breast_mastery_value limit = { is_alive = yes is_female = yes age >= 18 has_variable = domcom_breast_mastery_xp domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_order_breast_preferences_fullness_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_breast_fullness_value multiply = -1 } limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_breast_fullness_value limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_breast_preferences_frame_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_breast_frame_value multiply = -1 } limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_underbust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_breast_frame_value limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_underbust_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}
domcom_order_breast_preferences_both_effect = {
    if = { limit = { var:domcom_ui_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = { value = domcom_sort_pref_breast_both_value multiply = -1 } limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_underbust_tenths has_variable = domcom_pref_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_endowments_raw order_by = domcom_sort_pref_breast_both_value limit = { is_alive = yes age >= 18 is_attracted_to_women = yes has_variable = domcom_pref_underbust_tenths has_variable = domcom_pref_breast_fullness_tenths domcom_ui_roster_filter_trigger = yes } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_sorted_endowment scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_endowments target = scope:domcom_sorted_endowment } } }
    }
}

domcom_prepare_endowments_roster_effect = {
    # Opening the Registry is also an immediate repair point for an old save, so users do not need to
    # wait for the next quarterly population pulse to see corrected labels.
    domcom_migrate_endowment_classification_v19_once_effect = yes
    domcom_migrate_preference_classification_v110_once_effect = yes
    domcom_migrate_realistic_endowment_bands_v234_once_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_endowments_raw
    clear_variable_list = domcom_ui_endowments
    clear_variable_list = domcom_ui_endowments_page_list
    set_variable = { name = domcom_ui_endowments_count value = 0 }

    if = {
        limit = { NOT = { has_global_variable = domcom_endowment_registry_backfilled_v16 } }
        every_living_character = {
            limit = {
                is_male = yes age >= 18
                has_variable = domcom_length_tenths
                has_variable = domcom_girth_tenths
                NOT = { is_target_in_global_variable_list = { name = domcom_all_endowments target = this } }
            }
            add_to_global_variable_list = { name = domcom_all_endowments target = this }
        }
        set_global_variable = domcom_endowment_registry_backfilled_v16
    }

    if = {
        limit = { has_global_variable_list = domcom_all_endowments }
        every_in_global_list = {
            variable = domcom_all_endowments
            limit = {
                is_alive = yes is_male = yes age >= 18
                has_variable = domcom_length_tenths
                has_variable = domcom_girth_tenths
            }
            save_temporary_scope_as = domcom_endowment_subject
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_endowments_raw target = scope:domcom_endowment_subject }
                change_variable = { name = domcom_ui_endowments_count add = 1 }
            }
        }
    }

    domcom_rebuild_ui_rosters_effect = yes
}

# Build a lightweight list of every living current Lover/Soulmate of the Patron. This is deliberately
# relationship-graph bounded and therefore safe even in a very old save. The GUI still receives only the
# current twenty-row page.
domcom_prepare_lovers_roster_effect = {
    clear_variable_list = domcom_ui_lovers_raw
    clear_variable_list = domcom_ui_lovers
    clear_variable_list = domcom_ui_lovers_page_list
    set_variable = { name = domcom_ui_lovers_count value = 0 }
    save_scope_as = domcom_ui_patron

    every_relation = {
        type = lover
        type = soulmate
        limit = { is_alive = yes NOT = { this = scope:domcom_ui_patron } }
        save_temporary_scope_as = domcom_ui_lover_ref
        scope:domcom_ui_patron = {
            if = {
                limit = {
                    NOT = {
                        any_in_list = {
                            variable = domcom_ui_lovers_raw
                            this = scope:domcom_ui_lover_ref
                        }
                    }
                }
                add_to_variable_list = { name = domcom_ui_lovers_raw target = scope:domcom_ui_lover_ref }
                change_variable = { name = domcom_ui_lovers_count add = 1 }
            }
        }
    }


    # Dominion-protected bonds remain listed even if another event removed the vanilla Lover relation.
    if = {
        limit = { has_variable_list = domcom_intimate_registry }
        every_in_list = {
            variable = domcom_intimate_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_communion_intimate_bound
                has_variable = domcom_communion_intimate_patron
                var:domcom_communion_intimate_patron = scope:domcom_ui_patron
            }
            save_temporary_scope_as = domcom_ui_lover_ref
            scope:domcom_ui_patron = {
                if = {
                    limit = { NOT = { any_in_list = { variable = domcom_ui_lovers_raw this = scope:domcom_ui_lover_ref } } }
                    add_to_variable_list = { name = domcom_ui_lovers_raw target = scope:domcom_ui_lover_ref }
                    change_variable = { name = domcom_ui_lovers_count add = 1 }
                }
            }
        }
    }

    if = {
        limit = { has_variable_list = domcom_ui_lovers_raw }
        ordered_in_list = {
            variable = domcom_ui_lovers_raw
            order_by = domcom_sort_rank_value
            max = 100000
            check_range_bounds = no
            save_temporary_scope_as = domcom_sorted_lover
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_lovers target = scope:domcom_sorted_lover }
            }
        }
    }
    domcom_build_lovers_page_effect = yes
}

domcom_standard_page_size_effect = {
    set_variable = { name = domcom_ui_standard_page_size value = 20 }
}

domcom_clear_standard_ui_page_caches_effect = {
    clear_variable_list = domcom_ui_cucked_page_list
    clear_variable_list = domcom_ui_owned_page_list
    clear_variable_list = domcom_ui_endowments_page_list
    clear_variable_list = domcom_ui_outcomes_page_list
    clear_variable_list = domcom_ui_lovers_page_list
    clear_variable_list = domcom_ui_prospects_page_list
    clear_variable_list = domcom_ui_blood_page_list
    clear_variable_list = domcom_ui_tantalized_page_list
    clear_variable_list = domcom_ui_secrets_page_list
    clear_variable_list = domcom_lick_page_list
}

domcom_build_cucked_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_cucked_page } } set_variable = { name = domcom_ui_cucked_page value = 0 } }
    clear_variable_list = domcom_ui_cucked_page_list

    set_variable = { name = domcom_ui_cucked_total value = 0 }
    set_variable = { name = domcom_ui_cucked_last_page value = 0 }
    set_variable = { name = domcom_ui_cucked_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_cucked_subjects }
        every_in_list = {
            variable = domcom_ui_cucked_subjects
            prev = {
                if = {
                    limit = { var:domcom_ui_cucked_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_cucked_last_page add = 1 }
                    set_variable = { name = domcom_ui_cucked_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_cucked_page_fill add = 1 }
                change_variable = { name = domcom_ui_cucked_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_cucked_page < 0 } set_variable = { name = domcom_ui_cucked_page value = 0 } }
    if = { limit = { var:domcom_ui_cucked_page > var:domcom_ui_cucked_last_page } set_variable = { name = domcom_ui_cucked_page value = var:domcom_ui_cucked_last_page } }

    set_variable = { name = domcom_ui_cucked_first value = var:domcom_ui_cucked_page }
    change_variable = { name = domcom_ui_cucked_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_cucked_stop value = var:domcom_ui_cucked_first }
    change_variable = { name = domcom_ui_cucked_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_cucked_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_cucked_subjects }
        every_in_list = {
            variable = domcom_ui_cucked_subjects
            save_temporary_scope_as = domcom_cucked_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_cucked_index >= var:domcom_ui_cucked_first
                        var:domcom_ui_cucked_index < var:domcom_ui_cucked_stop
                    }
                    add_to_variable_list = { name = domcom_ui_cucked_page_list target = scope:domcom_cucked_page_row }
                }
                change_variable = { name = domcom_ui_cucked_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_cucked_shown_from value = var:domcom_ui_cucked_first }
    change_variable = { name = domcom_ui_cucked_shown_from add = 1 }
    set_variable = { name = domcom_ui_cucked_shown_to value = var:domcom_ui_cucked_stop }
    if = { limit = { var:domcom_ui_cucked_shown_to > var:domcom_ui_cucked_total } set_variable = { name = domcom_ui_cucked_shown_to value = var:domcom_ui_cucked_total } }
    set_variable = { name = domcom_ui_cucked_page_display value = var:domcom_ui_cucked_page }
    change_variable = { name = domcom_ui_cucked_page_display add = 1 }
    set_variable = { name = domcom_ui_cucked_pages_display value = var:domcom_ui_cucked_last_page }
    change_variable = { name = domcom_ui_cucked_pages_display add = 1 }
    if = { limit = { var:domcom_ui_cucked_total = 0 } set_variable = { name = domcom_ui_cucked_shown_from value = 0 } }
}

domcom_build_owned_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_owned_page } } set_variable = { name = domcom_ui_owned_page value = 0 } }
    clear_variable_list = domcom_ui_owned_page_list

    set_variable = { name = domcom_ui_owned_total value = 0 }
    set_variable = { name = domcom_ui_owned_last_page value = 0 }
    set_variable = { name = domcom_ui_owned_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_owned_subjects }
        every_in_list = {
            variable = domcom_ui_owned_subjects
            prev = {
                if = {
                    limit = { var:domcom_ui_owned_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_owned_last_page add = 1 }
                    set_variable = { name = domcom_ui_owned_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_owned_page_fill add = 1 }
                change_variable = { name = domcom_ui_owned_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_owned_page < 0 } set_variable = { name = domcom_ui_owned_page value = 0 } }
    if = { limit = { var:domcom_ui_owned_page > var:domcom_ui_owned_last_page } set_variable = { name = domcom_ui_owned_page value = var:domcom_ui_owned_last_page } }

    set_variable = { name = domcom_ui_owned_first value = var:domcom_ui_owned_page }
    change_variable = { name = domcom_ui_owned_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_owned_stop value = var:domcom_ui_owned_first }
    change_variable = { name = domcom_ui_owned_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_owned_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_owned_subjects }
        every_in_list = {
            variable = domcom_ui_owned_subjects
            save_temporary_scope_as = domcom_owned_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_owned_index >= var:domcom_ui_owned_first
                        var:domcom_ui_owned_index < var:domcom_ui_owned_stop
                    }
                    add_to_variable_list = { name = domcom_ui_owned_page_list target = scope:domcom_owned_page_row }
                }
                change_variable = { name = domcom_ui_owned_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_owned_shown_from value = var:domcom_ui_owned_first }
    change_variable = { name = domcom_ui_owned_shown_from add = 1 }
    set_variable = { name = domcom_ui_owned_shown_to value = var:domcom_ui_owned_stop }
    if = { limit = { var:domcom_ui_owned_shown_to > var:domcom_ui_owned_total } set_variable = { name = domcom_ui_owned_shown_to value = var:domcom_ui_owned_total } }
    set_variable = { name = domcom_ui_owned_page_display value = var:domcom_ui_owned_page }
    change_variable = { name = domcom_ui_owned_page_display add = 1 }
    set_variable = { name = domcom_ui_owned_pages_display value = var:domcom_ui_owned_last_page }
    change_variable = { name = domcom_ui_owned_pages_display add = 1 }
    if = { limit = { var:domcom_ui_owned_total = 0 } set_variable = { name = domcom_ui_owned_shown_from value = 0 } }
}

domcom_build_endowments_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_endowments_page } } set_variable = { name = domcom_ui_endowments_page value = 0 } }
    clear_variable_list = domcom_ui_endowments_page_list

    set_variable = { name = domcom_ui_endowments_total value = 0 }
    set_variable = { name = domcom_ui_endowments_last_page value = 0 }
    set_variable = { name = domcom_ui_endowments_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_endowments }
        every_in_list = {
            variable = domcom_ui_endowments
            prev = {
                if = {
                    limit = { var:domcom_ui_endowments_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_endowments_last_page add = 1 }
                    set_variable = { name = domcom_ui_endowments_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_endowments_page_fill add = 1 }
                change_variable = { name = domcom_ui_endowments_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_endowments_page < 0 } set_variable = { name = domcom_ui_endowments_page value = 0 } }
    if = { limit = { var:domcom_ui_endowments_page > var:domcom_ui_endowments_last_page } set_variable = { name = domcom_ui_endowments_page value = var:domcom_ui_endowments_last_page } }

    set_variable = { name = domcom_ui_endowments_first value = var:domcom_ui_endowments_page }
    change_variable = { name = domcom_ui_endowments_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_endowments_stop value = var:domcom_ui_endowments_first }
    change_variable = { name = domcom_ui_endowments_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_endowments_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_endowments }
        every_in_list = {
            variable = domcom_ui_endowments
            save_temporary_scope_as = domcom_endowments_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_endowments_index >= var:domcom_ui_endowments_first
                        var:domcom_ui_endowments_index < var:domcom_ui_endowments_stop
                    }
                    add_to_variable_list = { name = domcom_ui_endowments_page_list target = scope:domcom_endowments_page_row }
                }
                change_variable = { name = domcom_ui_endowments_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_endowments_shown_from value = var:domcom_ui_endowments_first }
    change_variable = { name = domcom_ui_endowments_shown_from add = 1 }
    set_variable = { name = domcom_ui_endowments_shown_to value = var:domcom_ui_endowments_stop }
    if = { limit = { var:domcom_ui_endowments_shown_to > var:domcom_ui_endowments_total } set_variable = { name = domcom_ui_endowments_shown_to value = var:domcom_ui_endowments_total } }
    set_variable = { name = domcom_ui_endowments_page_display value = var:domcom_ui_endowments_page }
    change_variable = { name = domcom_ui_endowments_page_display add = 1 }
    set_variable = { name = domcom_ui_endowments_pages_display value = var:domcom_ui_endowments_last_page }
    change_variable = { name = domcom_ui_endowments_pages_display add = 1 }
    if = { limit = { var:domcom_ui_endowments_total = 0 } set_variable = { name = domcom_ui_endowments_shown_from value = 0 } }
}

domcom_build_lovers_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_lovers_page } } set_variable = { name = domcom_ui_lovers_page value = 0 } }
    clear_variable_list = domcom_ui_lovers_page_list

    set_variable = { name = domcom_ui_lovers_total value = 0 }
    set_variable = { name = domcom_ui_lovers_last_page value = 0 }
    set_variable = { name = domcom_ui_lovers_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_lovers }
        every_in_list = {
            variable = domcom_ui_lovers
            prev = {
                if = {
                    limit = { var:domcom_ui_lovers_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_lovers_last_page add = 1 }
                    set_variable = { name = domcom_ui_lovers_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_lovers_page_fill add = 1 }
                change_variable = { name = domcom_ui_lovers_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_lovers_page < 0 } set_variable = { name = domcom_ui_lovers_page value = 0 } }
    if = { limit = { var:domcom_ui_lovers_page > var:domcom_ui_lovers_last_page } set_variable = { name = domcom_ui_lovers_page value = var:domcom_ui_lovers_last_page } }

    set_variable = { name = domcom_ui_lovers_first value = var:domcom_ui_lovers_page }
    change_variable = { name = domcom_ui_lovers_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_lovers_stop value = var:domcom_ui_lovers_first }
    change_variable = { name = domcom_ui_lovers_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_lovers_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_lovers }
        every_in_list = {
            variable = domcom_ui_lovers
            save_temporary_scope_as = domcom_lovers_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_lovers_index >= var:domcom_ui_lovers_first
                        var:domcom_ui_lovers_index < var:domcom_ui_lovers_stop
                    }
                    add_to_variable_list = { name = domcom_ui_lovers_page_list target = scope:domcom_lovers_page_row }
                }
                change_variable = { name = domcom_ui_lovers_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_lovers_shown_from value = var:domcom_ui_lovers_first }
    change_variable = { name = domcom_ui_lovers_shown_from add = 1 }
    set_variable = { name = domcom_ui_lovers_shown_to value = var:domcom_ui_lovers_stop }
    if = { limit = { var:domcom_ui_lovers_shown_to > var:domcom_ui_lovers_total } set_variable = { name = domcom_ui_lovers_shown_to value = var:domcom_ui_lovers_total } }
    set_variable = { name = domcom_ui_lovers_page_display value = var:domcom_ui_lovers_page }
    change_variable = { name = domcom_ui_lovers_page_display add = 1 }
    set_variable = { name = domcom_ui_lovers_pages_display value = var:domcom_ui_lovers_last_page }
    change_variable = { name = domcom_ui_lovers_pages_display add = 1 }
    if = { limit = { var:domcom_ui_lovers_total = 0 } set_variable = { name = domcom_ui_lovers_shown_from value = 0 } }
}

domcom_build_prospects_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_prospects_page } } set_variable = { name = domcom_ui_prospects_page value = 0 } }
    clear_variable_list = domcom_ui_prospects_page_list

    set_variable = { name = domcom_ui_prospects_total value = 0 }
    set_variable = { name = domcom_ui_prospects_last_page value = 0 }
    set_variable = { name = domcom_ui_prospects_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_prospects }
        every_in_list = {
            variable = domcom_ui_prospects
            prev = {
                if = {
                    limit = { var:domcom_ui_prospects_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_prospects_last_page add = 1 }
                    set_variable = { name = domcom_ui_prospects_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_prospects_page_fill add = 1 }
                change_variable = { name = domcom_ui_prospects_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_prospects_page < 0 } set_variable = { name = domcom_ui_prospects_page value = 0 } }
    if = { limit = { var:domcom_ui_prospects_page > var:domcom_ui_prospects_last_page } set_variable = { name = domcom_ui_prospects_page value = var:domcom_ui_prospects_last_page } }

    set_variable = { name = domcom_ui_prospects_first value = var:domcom_ui_prospects_page }
    change_variable = { name = domcom_ui_prospects_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_prospects_stop value = var:domcom_ui_prospects_first }
    change_variable = { name = domcom_ui_prospects_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_prospects_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_prospects }
        every_in_list = {
            variable = domcom_ui_prospects
            save_temporary_scope_as = domcom_prospects_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_prospects_index >= var:domcom_ui_prospects_first
                        var:domcom_ui_prospects_index < var:domcom_ui_prospects_stop
                    }
                    add_to_variable_list = { name = domcom_ui_prospects_page_list target = scope:domcom_prospects_page_row }
                }
                change_variable = { name = domcom_ui_prospects_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_prospects_shown_from value = var:domcom_ui_prospects_first }
    change_variable = { name = domcom_ui_prospects_shown_from add = 1 }
    set_variable = { name = domcom_ui_prospects_shown_to value = var:domcom_ui_prospects_stop }
    if = { limit = { var:domcom_ui_prospects_shown_to > var:domcom_ui_prospects_total } set_variable = { name = domcom_ui_prospects_shown_to value = var:domcom_ui_prospects_total } }
    set_variable = { name = domcom_ui_prospects_page_display value = var:domcom_ui_prospects_page }
    change_variable = { name = domcom_ui_prospects_page_display add = 1 }
    set_variable = { name = domcom_ui_prospects_pages_display value = var:domcom_ui_prospects_last_page }
    change_variable = { name = domcom_ui_prospects_pages_display add = 1 }
    if = { limit = { var:domcom_ui_prospects_total = 0 } set_variable = { name = domcom_ui_prospects_shown_from value = 0 } }
}

domcom_build_blood_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_blood_page } } set_variable = { name = domcom_ui_blood_page value = 0 } }
    clear_variable_list = domcom_ui_blood_page_list

    set_variable = { name = domcom_ui_blood_total value = 0 }
    set_variable = { name = domcom_ui_blood_last_page value = 0 }
    set_variable = { name = domcom_ui_blood_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_blood_children }
        every_in_list = {
            variable = domcom_ui_blood_children
            prev = {
                if = {
                    limit = { var:domcom_ui_blood_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_blood_last_page add = 1 }
                    set_variable = { name = domcom_ui_blood_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_blood_page_fill add = 1 }
                change_variable = { name = domcom_ui_blood_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_blood_page < 0 } set_variable = { name = domcom_ui_blood_page value = 0 } }
    if = { limit = { var:domcom_ui_blood_page > var:domcom_ui_blood_last_page } set_variable = { name = domcom_ui_blood_page value = var:domcom_ui_blood_last_page } }

    set_variable = { name = domcom_ui_blood_first value = var:domcom_ui_blood_page }
    change_variable = { name = domcom_ui_blood_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_blood_stop value = var:domcom_ui_blood_first }
    change_variable = { name = domcom_ui_blood_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_blood_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_blood_children }
        every_in_list = {
            variable = domcom_ui_blood_children
            save_temporary_scope_as = domcom_blood_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_blood_index >= var:domcom_ui_blood_first
                        var:domcom_ui_blood_index < var:domcom_ui_blood_stop
                    }
                    add_to_variable_list = { name = domcom_ui_blood_page_list target = scope:domcom_blood_page_row }
                }
                change_variable = { name = domcom_ui_blood_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_blood_shown_from value = var:domcom_ui_blood_first }
    change_variable = { name = domcom_ui_blood_shown_from add = 1 }
    set_variable = { name = domcom_ui_blood_shown_to value = var:domcom_ui_blood_stop }
    if = { limit = { var:domcom_ui_blood_shown_to > var:domcom_ui_blood_total } set_variable = { name = domcom_ui_blood_shown_to value = var:domcom_ui_blood_total } }
    set_variable = { name = domcom_ui_blood_page_display value = var:domcom_ui_blood_page }
    change_variable = { name = domcom_ui_blood_page_display add = 1 }
    set_variable = { name = domcom_ui_blood_pages_display value = var:domcom_ui_blood_last_page }
    change_variable = { name = domcom_ui_blood_pages_display add = 1 }
    if = { limit = { var:domcom_ui_blood_total = 0 } set_variable = { name = domcom_ui_blood_shown_from value = 0 } }
}

domcom_build_tantalized_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_tantalized_page } } set_variable = { name = domcom_ui_tantalized_page value = 0 } }
    clear_variable_list = domcom_ui_tantalized_page_list

    set_variable = { name = domcom_ui_tantalized_total value = 0 }
    set_variable = { name = domcom_ui_tantalized_last_page value = 0 }
    set_variable = { name = domcom_ui_tantalized_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_tantalized }
        every_in_list = {
            variable = domcom_ui_tantalized
            prev = {
                if = {
                    limit = { var:domcom_ui_tantalized_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_tantalized_last_page add = 1 }
                    set_variable = { name = domcom_ui_tantalized_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_tantalized_page_fill add = 1 }
                change_variable = { name = domcom_ui_tantalized_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_tantalized_page < 0 } set_variable = { name = domcom_ui_tantalized_page value = 0 } }
    if = { limit = { var:domcom_ui_tantalized_page > var:domcom_ui_tantalized_last_page } set_variable = { name = domcom_ui_tantalized_page value = var:domcom_ui_tantalized_last_page } }

    set_variable = { name = domcom_ui_tantalized_first value = var:domcom_ui_tantalized_page }
    change_variable = { name = domcom_ui_tantalized_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_tantalized_stop value = var:domcom_ui_tantalized_first }
    change_variable = { name = domcom_ui_tantalized_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_tantalized_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_tantalized }
        every_in_list = {
            variable = domcom_ui_tantalized
            save_temporary_scope_as = domcom_tantalized_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_tantalized_index >= var:domcom_ui_tantalized_first
                        var:domcom_ui_tantalized_index < var:domcom_ui_tantalized_stop
                    }
                    add_to_variable_list = { name = domcom_ui_tantalized_page_list target = scope:domcom_tantalized_page_row }
                }
                change_variable = { name = domcom_ui_tantalized_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_tantalized_shown_from value = var:domcom_ui_tantalized_first }
    change_variable = { name = domcom_ui_tantalized_shown_from add = 1 }
    set_variable = { name = domcom_ui_tantalized_shown_to value = var:domcom_ui_tantalized_stop }
    if = { limit = { var:domcom_ui_tantalized_shown_to > var:domcom_ui_tantalized_total } set_variable = { name = domcom_ui_tantalized_shown_to value = var:domcom_ui_tantalized_total } }
    set_variable = { name = domcom_ui_tantalized_page_display value = var:domcom_ui_tantalized_page }
    change_variable = { name = domcom_ui_tantalized_page_display add = 1 }
    set_variable = { name = domcom_ui_tantalized_pages_display value = var:domcom_ui_tantalized_last_page }
    change_variable = { name = domcom_ui_tantalized_pages_display add = 1 }
    if = { limit = { var:domcom_ui_tantalized_total = 0 } set_variable = { name = domcom_ui_tantalized_shown_from value = 0 } }
}

domcom_build_secrets_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_secrets_page } } set_variable = { name = domcom_ui_secrets_page value = 0 } }
    clear_variable_list = domcom_ui_secrets_page_list
    clear_variable_list = domcom_lick_page_list

    set_variable = { name = domcom_ui_secrets_total value = 0 }
    set_variable = { name = domcom_ui_secrets_last_page value = 0 }
    set_variable = { name = domcom_ui_secrets_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_owned_subjects }
        every_in_list = {
            variable = domcom_ui_owned_subjects
            prev = {
                if = {
                    limit = { var:domcom_ui_secrets_page_fill >= var:domcom_ui_standard_page_size }
                    change_variable = { name = domcom_ui_secrets_last_page add = 1 }
                    set_variable = { name = domcom_ui_secrets_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_secrets_page_fill add = 1 }
                change_variable = { name = domcom_ui_secrets_total add = 1 }
            }
        }
    }

    if = { limit = { var:domcom_ui_secrets_page < 0 } set_variable = { name = domcom_ui_secrets_page value = 0 } }
    if = { limit = { var:domcom_ui_secrets_page > var:domcom_ui_secrets_last_page } set_variable = { name = domcom_ui_secrets_page value = var:domcom_ui_secrets_last_page } }

    set_variable = { name = domcom_ui_secrets_first value = var:domcom_ui_secrets_page }
    change_variable = { name = domcom_ui_secrets_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_secrets_stop value = var:domcom_ui_secrets_first }
    change_variable = { name = domcom_ui_secrets_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_secrets_index value = 0 }

    if = {
        limit = { has_variable_list = domcom_ui_owned_subjects }
        every_in_list = {
            variable = domcom_ui_owned_subjects
            save_temporary_scope_as = domcom_secrets_page_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_secrets_index >= var:domcom_ui_secrets_first
                        var:domcom_ui_secrets_index < var:domcom_ui_secrets_stop
                    }
                    add_to_variable_list = { name = domcom_ui_secrets_page_list target = scope:domcom_secrets_page_row }
                }
                change_variable = { name = domcom_ui_secrets_index add = 1 }
            }
        }
    }

    set_variable = { name = domcom_ui_secrets_shown_from value = var:domcom_ui_secrets_first }
    change_variable = { name = domcom_ui_secrets_shown_from add = 1 }
    set_variable = { name = domcom_ui_secrets_shown_to value = var:domcom_ui_secrets_stop }
    if = { limit = { var:domcom_ui_secrets_shown_to > var:domcom_ui_secrets_total } set_variable = { name = domcom_ui_secrets_shown_to value = var:domcom_ui_secrets_total } }
    set_variable = { name = domcom_ui_secrets_page_display value = var:domcom_ui_secrets_page }
    change_variable = { name = domcom_ui_secrets_page_display add = 1 }
    set_variable = { name = domcom_ui_secrets_pages_display value = var:domcom_ui_secrets_last_page }
    change_variable = { name = domcom_ui_secrets_pages_display add = 1 }
    if = { limit = { var:domcom_ui_secrets_total = 0 } set_variable = { name = domcom_ui_secrets_shown_from value = 0 } }
}

domcom_build_standard_ui_pages_effect = {
    domcom_build_cucked_page_effect = yes
    domcom_build_owned_page_effect = yes
    domcom_build_endowments_page_effect = yes
    domcom_build_lovers_page_effect = yes
    domcom_build_prospects_page_effect = yes
    domcom_build_blood_page_effect = yes
    domcom_build_tantalized_page_effect = yes
    domcom_build_secrets_page_effect = yes
}


domcom_refresh_owned_benefit_tier_effect = {
    set_variable = { name = domcom_owned_bonus_count value = 0 }
    set_variable = { name = domcom_owned_bonus_tier value = 0 }
    set_variable = { name = domcom_owned_bonus_monthly value = 0 }
    set_variable = { name = domcom_owned_bonus_legitimacy value = 0 }
    save_scope_as = domcom_owned_bonus_patron

    if = {
        limit = { is_ai = no has_variable_list = domcom_owned_registry }
        every_in_list = {
            variable = domcom_owned_registry
            limit = {
                is_alive = yes
                has_character_flag = domcom_owned_cuck
                has_variable = domcom_patron
                var:domcom_patron = scope:domcom_owned_bonus_patron
            }
            scope:domcom_owned_bonus_patron = { change_variable = { name = domcom_owned_bonus_count add = 1 } }
        }
    }

    if = {
        limit = { is_ai = no var:domcom_owned_bonus_count >= 10 }
        set_variable = { name = domcom_owned_bonus_tier value = 3 }
        set_variable = { name = domcom_owned_bonus_monthly value = 100 }
        set_variable = { name = domcom_owned_bonus_legitimacy value = 5 }
        remove_character_modifier = domcom_owned_benefit_tier_1_modifier
        remove_character_modifier = domcom_owned_benefit_tier_2_modifier
        if = { limit = { NOT = { has_character_modifier = domcom_owned_benefit_tier_3_modifier } } add_character_modifier = { modifier = domcom_owned_benefit_tier_3_modifier } }
    }
    else_if = {
        limit = { is_ai = no var:domcom_owned_bonus_count >= 5 }
        set_variable = { name = domcom_owned_bonus_tier value = 2 }
        set_variable = { name = domcom_owned_bonus_monthly value = 50 }
        set_variable = { name = domcom_owned_bonus_legitimacy value = 3 }
        remove_character_modifier = domcom_owned_benefit_tier_1_modifier
        remove_character_modifier = domcom_owned_benefit_tier_3_modifier
        if = { limit = { NOT = { has_character_modifier = domcom_owned_benefit_tier_2_modifier } } add_character_modifier = { modifier = domcom_owned_benefit_tier_2_modifier } }
    }
    else_if = {
        limit = { is_ai = no var:domcom_owned_bonus_count >= 1 }
        set_variable = { name = domcom_owned_bonus_tier value = 1 }
        set_variable = { name = domcom_owned_bonus_monthly value = 25 }
        set_variable = { name = domcom_owned_bonus_legitimacy value = 1 }
        remove_character_modifier = domcom_owned_benefit_tier_2_modifier
        remove_character_modifier = domcom_owned_benefit_tier_3_modifier
        if = { limit = { NOT = { has_character_modifier = domcom_owned_benefit_tier_1_modifier } } add_character_modifier = { modifier = domcom_owned_benefit_tier_1_modifier } }
    }
    else = {
        remove_character_modifier = domcom_owned_benefit_tier_1_modifier
        remove_character_modifier = domcom_owned_benefit_tier_2_modifier
        remove_character_modifier = domcom_owned_benefit_tier_3_modifier
    }
}

domcom_owned_legitimacy_quarterly_effect = {
    if = {
        limit = { is_ai = no is_alive = yes }
        domcom_refresh_owned_benefit_tier_effect = yes
        if = { limit = { is_landed = yes var:domcom_owned_bonus_tier = 1 } add_legitimacy = 1 }
        else_if = { limit = { is_landed = yes var:domcom_owned_bonus_tier = 2 } add_legitimacy = 3 }
        else_if = { limit = { is_landed = yes var:domcom_owned_bonus_tier = 3 } add_legitimacy = 5 }
    }
}


# -----------------------------------------------------------------------------
# WORLD ALPHA GAUNTLET
# -----------------------------------------------------------------------------

# Run from a successfully challenged World Cuck. These are already Cucked by somebody else, so a World
# Gauntlet victory must NOT overwrite domcom_cuck_origin_patron/domcom_cuck_patron. It establishes the
# player's ordinary pre-cuck Dominated relationship and takes one quarter of the target's positive liquid
# resources as spoils.
domcom_world_gauntlet_success_effect = {
    save_scope_as = domcom_world_gauntlet_target

    scope:domcom_world_gauntlet_patron = { save_scope_as = domcom_owner }
    domcom_apply_dominated_effect = yes

    # Gold is an actual transfer.
    if = {
        limit = { gold > 0 }
        set_variable = { name = domcom_world_gauntlet_gold_prize value = gold }
        change_variable = { name = domcom_world_gauntlet_gold_prize multiply = 0.25 }
        pay_short_term_gold = { target = scope:domcom_world_gauntlet_patron gold = var:domcom_world_gauntlet_gold_prize }
        remove_variable = domcom_world_gauntlet_gold_prize
    }

    # Prestige and Piety are transferred rather than copied.
    if = {
        limit = { prestige > 0 }
        set_variable = { name = domcom_world_gauntlet_prestige_prize value = prestige }
        change_variable = { name = domcom_world_gauntlet_prestige_prize multiply = 0.25 }
        scope:domcom_world_gauntlet_patron = {
            add_prestige = { value = scope:domcom_world_gauntlet_target.var:domcom_world_gauntlet_prestige_prize }
        }
        add_prestige = { value = var:domcom_world_gauntlet_prestige_prize multiply = -1 }
        remove_variable = domcom_world_gauntlet_prestige_prize
    }
    if = {
        limit = { piety > 0 }
        set_variable = { name = domcom_world_gauntlet_piety_prize value = piety }
        change_variable = { name = domcom_world_gauntlet_piety_prize multiply = 0.25 }
        scope:domcom_world_gauntlet_patron = {
            add_piety = { value = scope:domcom_world_gauntlet_target.var:domcom_world_gauntlet_piety_prize }
        }
        add_piety = { value = var:domcom_world_gauntlet_piety_prize multiply = -1 }
        remove_variable = domcom_world_gauntlet_piety_prize
    }

    # Renown belongs to dynasties, not individuals. A successful target therefore yields one quarter of
    # the renown currently held by their dynasty. Repeated members of the same dynasty naturally yield a
    # diminishing quarter of the remaining pool rather than duplicating a snapshot.
    if = {
        limit = {
            exists = dynasty
            scope:domcom_world_gauntlet_patron = { exists = dynasty }
        }
        scope:domcom_world_gauntlet_patron.dynasty = { save_temporary_scope_as = domcom_world_gauntlet_patron_dynasty }
        dynasty = {
            save_temporary_scope_as = domcom_world_gauntlet_target_dynasty
            if = {
                limit = {
                    dynasty_prestige > 0
                    NOT = { this = scope:domcom_world_gauntlet_patron_dynasty }
                }
                set_variable = { name = domcom_world_gauntlet_renown_prize value = dynasty_prestige }
                change_variable = { name = domcom_world_gauntlet_renown_prize multiply = 0.25 }
                scope:domcom_world_gauntlet_patron_dynasty = {
                    add_dynasty_prestige = { value = scope:domcom_world_gauntlet_target_dynasty.var:domcom_world_gauntlet_renown_prize }
                }
                add_dynasty_prestige = { value = var:domcom_world_gauntlet_renown_prize multiply = -1 }
                remove_variable = domcom_world_gauntlet_renown_prize
            }
        }
    }

    # Keep cultures represented by successful targets so Tier II/III can steal innovations the player's
    # culture is actually eligible to learn. Variable lists accept non-character scopes.
    culture = { save_temporary_scope_as = domcom_world_gauntlet_source_culture }
    scope:domcom_world_gauntlet_patron = {
        if = {
            limit = {
                exists = culture
                culture = { can_get_innovation_from = scope:domcom_world_gauntlet_source_culture }
            }
            add_to_variable_list = {
                name = domcom_world_gauntlet_innovation_cultures
                target = scope:domcom_world_gauntlet_source_culture
            }
        }
    }
}

# Gain enough legitimacy to cross at least one legitimacy stage in ordinary governments, without an
# unbounded loop if a government caps the character below the normal level-5 ceiling.
domcom_world_gauntlet_raise_legitimacy_stage_effect = {
    if = {
        limit = { has_legitimacy = yes legitimacy_level < 5 }
        set_variable = { name = domcom_world_gauntlet_start_legitimacy_level value = legitimacy_level }
        set_variable = { name = domcom_world_gauntlet_legitimacy_guard value = 0 }
        while = {
            limit = {
                var:domcom_world_gauntlet_legitimacy_guard < 100
                legitimacy_level <= var:domcom_world_gauntlet_start_legitimacy_level
            }
            add_legitimacy = 25
            change_variable = { name = domcom_world_gauntlet_legitimacy_guard add = 1 }
        }
        remove_variable = domcom_world_gauntlet_start_legitimacy_level
        remove_variable = domcom_world_gauntlet_legitimacy_guard
    }
}

# Grant one innovation from a culture represented among successful targets, if that culture still has
# something the player's culture can learn at reward time.
domcom_world_gauntlet_grant_one_innovation_effect = {
    if = {
        limit = { has_variable_list = domcom_world_gauntlet_innovation_cultures exists = culture }
        random_in_list = {
            variable = domcom_world_gauntlet_innovation_cultures
            save_temporary_scope_as = domcom_world_gauntlet_innovation_source
            scope:domcom_world_gauntlet_patron = {
                culture = {
                    if = {
                        limit = { can_get_innovation_from = scope:domcom_world_gauntlet_innovation_source }
                        get_random_innovation_from = scope:domcom_world_gauntlet_innovation_source
                        scope:domcom_world_gauntlet_patron = { change_variable = { name = domcom_world_gauntlet_innovations_gained add = 1 } }
                    }
                }
            }
        }
    }
}

# Apply the tier reached after the whole World Gauntlet resolves. Knight bonuses are mutually exclusive,
# but Dominion Unchallenged is retained in addition to them.
domcom_world_gauntlet_apply_rewards_effect = {
    remove_character_modifier = domcom_world_gauntlet_tier_1_modifier
    remove_character_modifier = domcom_world_gauntlet_tier_2_modifier
    remove_character_modifier = domcom_world_gauntlet_tier_3_modifier
    set_variable = { name = domcom_world_gauntlet_tier value = 0 }
    set_variable = { name = domcom_world_gauntlet_innovations_gained value = 0 }

    if = {
        limit = { var:domcom_world_gauntlet_cleared >= var:domcom_world_gauntlet_tier_3_gate }
        set_variable = { name = domcom_world_gauntlet_tier value = 3 }
        add_character_modifier = { modifier = domcom_dominion_unchallenged_modifier years = 5 }
        add_character_modifier = { modifier = domcom_world_gauntlet_tier_3_modifier years = 5 }
        domcom_world_gauntlet_raise_legitimacy_stage_effect = yes
        save_scope_as = domcom_world_gauntlet_patron
        domcom_world_gauntlet_grant_one_innovation_effect = yes
        domcom_world_gauntlet_grant_one_innovation_effect = yes
    }
    else_if = {
        limit = { var:domcom_world_gauntlet_cleared >= var:domcom_world_gauntlet_tier_2_gate }
        set_variable = { name = domcom_world_gauntlet_tier value = 2 }
        add_character_modifier = { modifier = domcom_dominion_unchallenged_modifier years = 5 }
        add_character_modifier = { modifier = domcom_world_gauntlet_tier_2_modifier years = 5 }
        domcom_world_gauntlet_raise_legitimacy_stage_effect = yes
        save_scope_as = domcom_world_gauntlet_patron
        domcom_world_gauntlet_grant_one_innovation_effect = yes
    }
    else_if = {
        limit = { var:domcom_world_gauntlet_cleared >= var:domcom_world_gauntlet_tier_1_gate }
        set_variable = { name = domcom_world_gauntlet_tier value = 1 }
        add_character_modifier = { modifier = domcom_dominion_unchallenged_modifier years = 5 }
        add_character_modifier = { modifier = domcom_world_gauntlet_tier_1_modifier years = 5 }
        domcom_world_gauntlet_raise_legitimacy_stage_effect = yes
    }
}

domcom_clear_world_ui_cache_effect = {
    clear_variable_list = domcom_ui_world_cucks_raw
    clear_variable_list = domcom_ui_world_cucks
    clear_variable_list = domcom_ui_world_page_list
}

domcom_collect_world_cuck_roster_effect = {
    domcom_clear_world_ui_cache_effect = yes
    set_variable = { name = domcom_ui_world_cuck_count value = 0 }
    save_scope_as = domcom_ui_patron

    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = {
                is_alive = yes
                age >= 18
                has_character_flag = domcom_cucked
                NOT = {
                    OR = {
                        any_in_list = {
                            variable = domcom_cuck_patrons
                            this = scope:domcom_ui_patron
                        }
                        AND = {
                            NOT = { has_variable_list = domcom_cuck_patrons }
                            has_variable = domcom_cuck_origin_patron
                            var:domcom_cuck_origin_patron = scope:domcom_ui_patron
                        }
                    }
                }
            }
            save_temporary_scope_as = domcom_world_cuck_ref
            scope:domcom_ui_patron = {
                add_to_variable_list = { name = domcom_ui_world_cucks_raw target = scope:domcom_world_cuck_ref }
                change_variable = { name = domcom_ui_world_cuck_count add = 1 }
            }
        }
    }
}

domcom_prepare_world_cucks_effect = {
    # 2.2.0 is a full tournament-model replacement. Give existing saves one immediate retry instead of
    # forcing them to wait out a cooldown earned under the retired bracket formulation.
    if = {
        limit = { NOT = { has_variable = domcom_world_tournament_v220_migrated } }
        remove_character_flag = domcom_world_alpha_tournament_recent
        set_variable = { name = domcom_world_tournament_v220_migrated value = 1 }
    }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_mode } } set_variable = { name = domcom_ui_sort_mode value = flag:rank } }
    if = { limit = { NOT = { exists = var:domcom_ui_sort_direction } } set_variable = { name = domcom_ui_sort_direction value = flag:descending } }
    domcom_collect_world_cuck_roster_effect = yes
    domcom_rebuild_world_cuck_roster_effect = yes
}

domcom_rebuild_world_cuck_roster_effect = {
    clear_variable_list = domcom_ui_world_cucks
    save_scope_as = domcom_ui_patron

    if = {
        limit = { has_variable_list = domcom_ui_world_cucks_raw }
        if = { limit = { var:domcom_ui_sort_mode = flag:rank } domcom_order_world_rank_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:endowment } domcom_order_world_endowment_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:xp } domcom_order_world_xp_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:diplomacy } domcom_order_world_diplomacy_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:martial } domcom_order_world_martial_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:stewardship } domcom_order_world_stewardship_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:intrigue } domcom_order_world_intrigue_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:learning } domcom_order_world_learning_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prowess } domcom_order_world_prowess_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:total } domcom_order_world_total_effect = yes }
        else_if = { limit = { var:domcom_ui_sort_mode = flag:prize } domcom_order_world_prize_effect = yes }
        else = { domcom_order_world_xp_effect = yes }
    }

    domcom_build_world_cuck_page_effect = yes
}

domcom_world_page_size_effect = {
    set_variable = { name = domcom_ui_world_page_size value = 20 }
}

domcom_build_world_cuck_page_effect = {
    domcom_world_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_world_page } } set_variable = { name = domcom_ui_world_page value = 0 } }
    clear_variable_list = domcom_ui_world_page_list

    # Derive an integer page count without division. Script variables are numeric, so a raw (total - 1) /
    # 20 can leave a fractional last-page value.
    set_variable = { name = domcom_ui_world_total value = 0 }
    set_variable = { name = domcom_ui_world_last_page value = 0 }
    set_variable = { name = domcom_ui_world_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_world_cucks }
        every_in_list = {
            variable = domcom_ui_world_cucks
            prev = {
                if = {
                    limit = { var:domcom_ui_world_page_fill >= var:domcom_ui_world_page_size }
                    change_variable = { name = domcom_ui_world_last_page add = 1 }
                    set_variable = { name = domcom_ui_world_page_fill value = 0 }
                }
                change_variable = { name = domcom_ui_world_page_fill add = 1 }
                change_variable = { name = domcom_ui_world_total add = 1 }
            }
        }
    }

    # Clamp the page if deaths or ownership/history changes shrank the roster.
    if = { limit = { var:domcom_ui_world_page < 0 } set_variable = { name = domcom_ui_world_page value = 0 } }
    if = { limit = { var:domcom_ui_world_page > var:domcom_ui_world_last_page } set_variable = { name = domcom_ui_world_page value = var:domcom_ui_world_last_page } }

    set_variable = { name = domcom_ui_world_first value = var:domcom_ui_world_page }
    change_variable = { name = domcom_ui_world_first multiply = var:domcom_ui_world_page_size }
    set_variable = { name = domcom_ui_world_stop value = var:domcom_ui_world_first }
    change_variable = { name = domcom_ui_world_stop add = var:domcom_ui_world_page_size }

    set_variable = { name = domcom_ui_world_index value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_world_cucks }
        every_in_list = {
            variable = domcom_ui_world_cucks
            save_temporary_scope_as = domcom_world_row
            prev = {
                if = {
                    limit = {
                        var:domcom_ui_world_index >= var:domcom_ui_world_first
                        var:domcom_ui_world_index < var:domcom_ui_world_stop
                    }
                    add_to_variable_list = { name = domcom_ui_world_page_list target = scope:domcom_world_row }
                }
                change_variable = { name = domcom_ui_world_index add = 1 }
            }
        }
    }

    if = {
        limit = { has_variable_list = domcom_ui_world_page_list }
        every_in_list = {
            variable = domcom_ui_world_page_list
            domcom_initialize_profile_effect = yes
            domcom_refresh_cuck_stage_effect = yes
            domcom_refresh_cuck_reputation_effect = yes
        }
    }

    set_variable = { name = domcom_ui_world_shown_from value = var:domcom_ui_world_first }
    change_variable = { name = domcom_ui_world_shown_from add = 1 }
    set_variable = { name = domcom_ui_world_shown_to value = var:domcom_ui_world_stop }
    if = { limit = { var:domcom_ui_world_shown_to > var:domcom_ui_world_total } set_variable = { name = domcom_ui_world_shown_to value = var:domcom_ui_world_total } }
    set_variable = { name = domcom_ui_world_page_display value = var:domcom_ui_world_page }
    change_variable = { name = domcom_ui_world_page_display add = 1 }
    set_variable = { name = domcom_ui_world_pages_display value = var:domcom_ui_world_last_page }
    change_variable = { name = domcom_ui_world_pages_display add = 1 }
    if = { limit = { var:domcom_ui_world_total = 0 } set_variable = { name = domcom_ui_world_shown_from value = 0 } }
}

domcom_world_page_next_effect = {
    change_variable = { name = domcom_ui_world_page add = 1 }
    domcom_build_world_cuck_page_effect = yes
}

domcom_world_page_prev_effect = {
    change_variable = { name = domcom_ui_world_page subtract = 1 }
    if = { limit = { var:domcom_ui_world_page < 0 } set_variable = { name = domcom_ui_world_page value = 0 } }
    domcom_build_world_cuck_page_effect = yes
}

domcom_world_page_first_effect = {
    set_variable = { name = domcom_ui_world_page value = 0 }
    domcom_build_world_cuck_page_effect = yes
}


domcom_digest_note_admirer_effect = {
    if = {
        limit = { NOT = { has_variable = domcom_digest_pending } }
        set_variable = { name = domcom_digest_pending value = 0 }
    }
    change_variable = { name = domcom_digest_pending add = 1 }
}

# One non-pausing pulse replaces the old monthly prospect event and the automatic Final Collapse
# popups. Only strategically valuable new prospects contribute to the alert; ordinary successful
# attraction checks remain silently available in Dynastic Prospects.
domcom_quarterly_dominion_digest_effect = {
    domcom_initialize_ledger_counters_effect = yes
    if = {
        limit = {
            OR = {
                var:domcom_featured_digest_pending > 0
                var:domcom_collapse_digest_pending > 0
            }
        }
        set_variable = { name = domcom_last_pulse_featured value = var:domcom_featured_digest_pending }
        set_variable = { name = domcom_last_pulse_collapses value = var:domcom_collapse_digest_pending }
        send_interface_toast = {
            type = event_toast_effect_good
            title = domcom_dominion_pulse_toast_title
            left_icon = root
            if = {
                limit = { var:domcom_featured_digest_pending > 0 }
                custom_tooltip = domcom_dominion_pulse_prospects_line
            }
            if = {
                limit = { var:domcom_collapse_digest_pending > 0 }
                custom_tooltip = domcom_dominion_pulse_collapses_line
            }
            custom_tooltip = domcom_dominion_pulse_ledger_line
        }
    }
    set_variable = { name = domcom_digest_pending value = 0 }
    set_variable = { name = domcom_featured_digest_pending value = 0 }
    set_variable = { name = domcom_collapse_digest_pending value = 0 }
}

# Legacy alias retained so old references/save state cannot create a missing scripted effect.
domcom_monthly_digest_effect = {
    # Intentionally silent in 1.5; the quarterly Dominion Pulse owns notifications.
}


domcom_form_crowned_union_effect = {
    save_scope_as = domcom_crowned_queen
    remove_character_flag = domcom_crowned_union_completed

    if = {
        limit = {
            exists = primary_spouse
            primary_spouse = {
                is_alive = yes
                NOT = { this = scope:domcom_crowned_partner }
            }
        }
        primary_spouse = {
            save_scope_as = domcom_crowned_old_spouse
            divorce = scope:domcom_crowned_queen
        }
    }

    if = {
        limit = {
            can_marry_trigger = yes
            allowed_to_marry_character_gender_trigger = { CHARACTER = scope:domcom_crowned_partner }
            scope:domcom_crowned_partner = {
                can_marry_trigger = yes
                allowed_to_marry_character_gender_trigger = { CHARACTER = scope:domcom_crowned_queen }
            }
        }
        marry_on_realm_law = {
            SPOUSE_1 = scope:domcom_crowned_partner
            SPOUSE_2 = scope:domcom_crowned_queen
        }
        add_character_flag = domcom_crowned_union_completed
        add_opinion = { target = scope:domcom_crowned_partner modifier = domcom_crowned_union_devotion_opinion }

        if = {
            limit = { exists = scope:domcom_crowned_old_spouse }
            scope:domcom_crowned_old_spouse = {
                add_opinion = { target = scope:domcom_crowned_queen modifier = domcom_crowned_union_betrayed_opinion }
                add_opinion = { target = scope:domcom_crowned_partner modifier = domcom_crowned_union_betrayed_opinion }
            }
        }
    }
    else = {
        if = {
            limit = {
                exists = scope:domcom_crowned_old_spouse
                scope:domcom_crowned_old_spouse = { is_alive = yes can_marry_trigger = yes }
                can_marry_trigger = yes
            }
            marry_on_realm_law = {
                SPOUSE_1 = scope:domcom_crowned_queen
                SPOUSE_2 = scope:domcom_crowned_old_spouse
            }
        }
    }
}

domcom_ai_try_crowned_heart_effect = {
    save_scope_as = domcom_crowned_queen

    every_player = {
        limit = {
            is_ai = no
            is_alive = yes
            age >= 18
            is_imprisoned = no
            can_marry_trigger = yes
            scope:domcom_crowned_queen = {
                NOT = { has_character_flag = domcom_crowned_offer_pending }
                NOT = { has_character_flag = domcom_crowned_heart_rejected }
                domcom_crowned_heart_actor_trigger = yes
                domcom_crowned_union_pair_trigger = { PARTNER = prev }
                is_attracted_to_gender_of = prev
            }
        }

        save_scope_as = domcom_crowned_partner
        scope:domcom_crowned_queen = {
            domcom_initialize_attraction_profile_effect = yes
            scope:domcom_crowned_partner = { save_scope_as = domcom_compatibility_target }
            set_variable = { name = domcom_last_crowned_compatibility value = domcom_pair_compatibility_value }

            if = {
                limit = {
                    OR = {
                        var:domcom_last_crowned_compatibility >= 75
                        AND = {
                            var:domcom_last_crowned_compatibility >= 50
                            OR = {
                                has_relation_crush = scope:domcom_crowned_partner
                                has_relation_lover = scope:domcom_crowned_partner
                                has_relation_soulmate = scope:domcom_crowned_partner
                                AND = {
                                    has_character_flag = domcom_pet
                                    has_variable = domcom_pet_patron
                                    var:domcom_pet_patron = scope:domcom_crowned_partner
                                }
                            }
                        }
                    }
                }
                random = {
                    chance = domcom_crowned_heart_offer_chance_value
                    add_character_flag = { flag = domcom_crowned_offer_pending years = 2 }
                    scope:domcom_crowned_partner = {
                        trigger_event = { id = domcom.920 days = 1 }
                    }
                }
            }
        }
    }
}

domcom_deep_scan_effect = {
    save_scope_as = domcom_ui_patron
    save_scope_as = domcom_owner
    save_scope_as = domcom_scan_patron

    every_living_character = {
        limit = {
            domcom_is_unacknowledged_blood_trigger = yes
            NOT = { has_character_flag = domcom_blood_registered }
        }
        add_character_flag = domcom_blood_registered
        save_temporary_scope_as = domcom_scan_child
        scope:domcom_scan_patron = {
            add_to_variable_list = { name = domcom_blood_registry target = scope:domcom_scan_child }
        }
    }

    every_living_character = {
        limit = {
            is_alive = yes
            age >= 18
            NOT = { this = scope:domcom_scan_patron }
            domcom_has_qualifying_cuck_evidence_from_patron_trigger = { PATRON = scope:domcom_scan_patron }
        }
        domcom_register_cuck_generic_effect = yes
    }

    # --- 3. TANTALIZED --------------------------------------------------- Obedience was already
    # persisted per character; it simply was never collected anywhere the Patron could read it.
    every_living_character = {
        limit = {
            is_alive = yes
            age >= 18
            has_variable = domcom_obedience_patron
            var:domcom_obedience_patron = scope:domcom_scan_patron
            has_variable = domcom_obedience
            var:domcom_obedience > 0
            NOT = { has_character_flag = domcom_tantalized_registered }
        }
        add_character_flag = domcom_tantalized_registered
        save_temporary_scope_as = domcom_scan_tantalized
        scope:domcom_scan_patron = {
            add_to_variable_list = { name = domcom_tantalized_registry target = scope:domcom_scan_tantalized }
        }
    }

    # --- 4. OWNED -------------------------------------------------------- Repair the Patron-local Owned
    # registry from world state, so a save whose dynasty storage was lost or never written still reports
    # correctly.
    every_living_character = {
        limit = {
            is_alive = yes
            has_character_flag = domcom_owned_cuck
            has_variable = domcom_patron
            var:domcom_patron = scope:domcom_scan_patron
        }
        save_temporary_scope_as = domcom_scan_owned
        scope:domcom_scan_patron = {
            if = {
                limit = {
                    OR = {
                        NOT = { has_variable_list = domcom_owned_registry }
                        NOT = { any_in_list = { variable = domcom_owned_registry this = scope:domcom_scan_owned } }
                    }
                }
                add_to_variable_list = { name = domcom_owned_registry target = scope:domcom_scan_owned }
            }
        }
    }
}

domcom_order_tantalized_effect = {
    ordered_in_list = {
        variable = domcom_ui_tantalized_raw
        order_by = { value = domcom_sort_tantalized_value }
        max = 100000 check_range_bounds = no
        limit = { domcom_tantalize_filter_trigger = yes }
        save_temporary_scope_as = domcom_ui_tantalized_entry
        scope:domcom_ui_patron = {
            add_to_variable_list = { name = domcom_ui_tantalized target = scope:domcom_ui_tantalized_entry }
        }
    }
}

domcom_close_tribute_season_effect = {
    clear_variable_list = domcom_tribute_pending
    set_variable = { name = domcom_tribute_pending_count value = 0 }
    remove_character_flag = domcom_tribute_season_active
    add_character_flag = { flag = domcom_tribute_cooldown years = 5 }
    trigger_event = { id = domcom.530 days = 1 }
}

domcom_spend_alpha_budget_effect = {
    if = { limit = { NOT = { has_variable = domcom_alpha_budget_used } } set_variable = { name = domcom_alpha_budget_used value = 0 } }
    change_variable = { name = domcom_alpha_budget_used add = 1 }
}

# Fires on the quarterly playable pulse for human players only. The pulse is per character rather than
# calendar-aligned, so "a quarter" means one pulse period.
domcom_reset_alpha_budget_effect = {
    set_variable = { name = domcom_alpha_budget_used value = 0 }
}


domcom_apply_obedience_weight_effect = {
    if = {
        limit = { has_game_rule = domcom_obedience_weight_off }
        domcom_clear_obedience_hard_modifiers_effect = yes
    }
    else = {
        if = {
            limit = { has_variable = domcom_obedience var:domcom_obedience >= 800 }
            if = {
                limit = {
                    OR = {
                        NOT = { has_character_modifier = domcom_obedience_devoted_hard_modifier }
                        has_character_modifier = domcom_obedience_interested_hard_modifier
                        has_character_modifier = domcom_obedience_tempted_hard_modifier
                        has_character_modifier = domcom_obedience_attached_hard_modifier
                        has_character_modifier = domcom_obedience_submissive_hard_modifier
                    }
                }
                domcom_clear_obedience_hard_modifiers_effect = yes
                add_character_modifier = domcom_obedience_devoted_hard_modifier
            }
        }
        else_if = {
            limit = { has_variable = domcom_obedience var:domcom_obedience >= 600 }
            if = {
                limit = {
                    OR = {
                        NOT = { has_character_modifier = domcom_obedience_submissive_hard_modifier }
                        has_character_modifier = domcom_obedience_interested_hard_modifier
                        has_character_modifier = domcom_obedience_tempted_hard_modifier
                        has_character_modifier = domcom_obedience_attached_hard_modifier
                        has_character_modifier = domcom_obedience_devoted_hard_modifier
                    }
                }
                domcom_clear_obedience_hard_modifiers_effect = yes
                add_character_modifier = domcom_obedience_submissive_hard_modifier
            }
        }
        else_if = {
            limit = { has_variable = domcom_obedience var:domcom_obedience >= 400 }
            if = {
                limit = {
                    OR = {
                        NOT = { has_character_modifier = domcom_obedience_attached_hard_modifier }
                        has_character_modifier = domcom_obedience_interested_hard_modifier
                        has_character_modifier = domcom_obedience_tempted_hard_modifier
                        has_character_modifier = domcom_obedience_submissive_hard_modifier
                        has_character_modifier = domcom_obedience_devoted_hard_modifier
                    }
                }
                domcom_clear_obedience_hard_modifiers_effect = yes
                add_character_modifier = domcom_obedience_attached_hard_modifier
            }
        }
        else_if = {
            limit = { has_variable = domcom_obedience var:domcom_obedience >= 200 }
            if = {
                limit = {
                    OR = {
                        NOT = { has_character_modifier = domcom_obedience_tempted_hard_modifier }
                        has_character_modifier = domcom_obedience_interested_hard_modifier
                        has_character_modifier = domcom_obedience_attached_hard_modifier
                        has_character_modifier = domcom_obedience_submissive_hard_modifier
                        has_character_modifier = domcom_obedience_devoted_hard_modifier
                    }
                }
                domcom_clear_obedience_hard_modifiers_effect = yes
                add_character_modifier = domcom_obedience_tempted_hard_modifier
            }
        }
        else_if = {
            limit = { has_variable = domcom_obedience var:domcom_obedience > 0 }
            if = {
                limit = {
                    OR = {
                        NOT = { has_character_modifier = domcom_obedience_interested_hard_modifier }
                        has_character_modifier = domcom_obedience_tempted_hard_modifier
                        has_character_modifier = domcom_obedience_attached_hard_modifier
                        has_character_modifier = domcom_obedience_submissive_hard_modifier
                        has_character_modifier = domcom_obedience_devoted_hard_modifier
                    }
                }
                domcom_clear_obedience_hard_modifiers_effect = yes
                add_character_modifier = domcom_obedience_interested_hard_modifier
            }
        }
        else = { domcom_clear_obedience_hard_modifiers_effect = yes }
    }
}

domcom_clear_obedience_hard_modifiers_effect = {
    if = { limit = { has_character_modifier = domcom_obedience_interested_hard_modifier } remove_character_modifier = domcom_obedience_interested_hard_modifier }
    if = { limit = { has_character_modifier = domcom_obedience_tempted_hard_modifier } remove_character_modifier = domcom_obedience_tempted_hard_modifier }
    if = { limit = { has_character_modifier = domcom_obedience_attached_hard_modifier } remove_character_modifier = domcom_obedience_attached_hard_modifier }
    if = { limit = { has_character_modifier = domcom_obedience_submissive_hard_modifier } remove_character_modifier = domcom_obedience_submissive_hard_modifier }
    if = { limit = { has_character_modifier = domcom_obedience_devoted_hard_modifier } remove_character_modifier = domcom_obedience_devoted_hard_modifier }
}

# Tolerance is keyed to Devotion rather than ownership flags. Attached (400) is the line: below it a
# bond is exposed; at or above it the bond is protected and restorable exactly as an Owned subject's
# always was.
domcom_obedience_grants_tolerance_trigger_effect = {
    if = {
        limit = {
            NOT = { has_game_rule = domcom_obedience_weight_off }
            has_variable = domcom_obedience
            var:domcom_obedience >= 400
            has_variable = domcom_obedience_patron
        }
        set_variable = { name = domcom_accepts_communion value = yes }
        add_character_flag = block_infidelity_flag
    }
}

# --- the jealousy pass ------------------------------------------------------ Called once when the
# Patron takes someone new, against every existing intimate except the newcomer. Bounded by harem size,
# so no world scan.
domcom_run_jealousy_pass_effect = {
    if = {
        limit = { NOT = { has_game_rule = domcom_obedience_weight_off } }
        save_temporary_scope_as = domcom_jealousy_patron
        every_in_list = {
            variable = domcom_intimate_registry
            limit = {
                is_alive = yes
                age >= 18
                NOT = { this = scope:domcom_jealousy_rival }
            }
            domcom_score_jealousy_effect = yes
        }
    }
}

domcom_score_jealousy_effect = {
    # Precompute both attraction readings; the score value reads them back.
    scope:domcom_jealousy_patron = { save_temporary_scope_as = domcom_compatibility_target }
    set_variable = { name = domcom_jealousy_attr_patron value = domcom_pair_compatibility_value }
    scope:domcom_jealousy_rival = { save_temporary_scope_as = domcom_compatibility_target }
    set_variable = { name = domcom_jealousy_attr_rival value = domcom_pair_compatibility_value }

    set_variable = { name = domcom_jealousy_tier value = domcom_jealousy_tier_value }
    remove_variable = domcom_jealousy_attr_patron
    remove_variable = domcom_jealousy_attr_rival

    domcom_apply_jealousy_tier_effect = yes
    if = { limit = { has_variable = domcom_obedience } domcom_apply_obedience_weight_effect = yes }
}

domcom_apply_jealousy_tier_effect = {
    if = { limit = { NOT = { has_variable = domcom_obedience } } set_variable = { name = domcom_obedience value = 0 } }

    # 0 — pleased. She thinks better of him for it, and of the newcomer.
    if = {
        limit = { var:domcom_jealousy_tier = 0 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_pleased_opinion opinion = 15 }
        add_opinion = { target = scope:domcom_jealousy_rival modifier = domcom_jealousy_pleased_opinion opinion = 20 }
        change_variable = { name = domcom_obedience add = 25 }
    }
    # 1 — indifferent. Nothing happens, and that is a result.
    else_if = { limit = { var:domcom_jealousy_tier = 1 } }
    # 2 — stung.
    else_if = {
        limit = { var:domcom_jealousy_tier = 2 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_stung_opinion opinion = -10 }
        change_variable = { name = domcom_obedience subtract = 25 }
    }
    # 3 — hurt.
    else_if = {
        limit = { var:domcom_jealousy_tier = 3 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_stung_opinion opinion = -20 }
        add_opinion = { target = scope:domcom_jealousy_rival modifier = domcom_jealousy_stung_opinion opinion = -15 }
        change_variable = { name = domcom_obedience subtract = 75 }
        if = { limit = { stress < 150 } add_stress = 15 }
    }
    # 4 — resentful. The bond may not survive.
    else_if = {
        limit = { var:domcom_jealousy_tier = 4 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_resentful_opinion opinion = -30 }
        add_opinion = { target = scope:domcom_jealousy_rival modifier = domcom_jealousy_resentful_opinion opinion = -25 }
        change_variable = { name = domcom_obedience subtract = 150 }
        if = { limit = { stress < 150 } add_stress = 25 }
        domcom_jealousy_maybe_break_bond_effect = { CHANCE = 40 }
    }
    # 5 — hostile.
    else_if = {
        limit = { var:domcom_jealousy_tier = 5 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_resentful_opinion opinion = -45 }
        add_opinion = { target = scope:domcom_jealousy_rival modifier = domcom_jealousy_resentful_opinion opinion = -40 }
        change_variable = { name = domcom_obedience subtract = 250 }
        if = { limit = { stress < 150 } add_stress = 35 }
        if = {
            limit = { NOT = { has_game_rule = domcom_obedience_weight_soft } }
            set_relation_rival = scope:domcom_jealousy_rival
        }
        domcom_jealousy_maybe_break_bond_effect = { CHANCE = 70 }
    }
    # 6 — dangerous.
    else_if = {
        limit = { var:domcom_jealousy_tier >= 6 }
        add_opinion = { target = scope:domcom_jealousy_patron modifier = domcom_jealousy_hostile_opinion opinion = -60 }
        add_opinion = { target = scope:domcom_jealousy_rival modifier = domcom_jealousy_hostile_opinion opinion = -60 }
        set_variable = { name = domcom_obedience value = 0 }
        if = { limit = { stress < 150 } add_stress = 45 }
        if = {
            limit = { NOT = { has_game_rule = domcom_obedience_weight_soft } }
            set_relation_rival = scope:domcom_jealousy_rival
            add_character_flag = domcom_jealousy_hostile
            set_variable = { name = domcom_jealousy_target value = scope:domcom_jealousy_rival }
            if = {
                limit = { NOT = { has_character_modifier = domcom_jealousy_hostile_modifier } }
                add_character_modifier = { modifier = domcom_jealousy_hostile_modifier years = 10 }
            }
            domcom_jealousy_maybe_break_bond_effect = { CHANCE = 100 }
        }
    }

    if = { limit = { var:domcom_obedience < 0 } set_variable = { name = domcom_obedience value = 0 } }
    remove_variable = domcom_jealousy_tier
}

# Soft never breaks a bond. Tolerance at Attached protects it regardless.
domcom_jealousy_maybe_break_bond_effect = {
    if = {
        limit = {
            NOT = { has_game_rule = domcom_obedience_weight_soft }
            NOT = { var:domcom_obedience >= 400 }
            NOT = { has_variable = domcom_accepts_communion }
            NOT = {
                AND = {
                    has_character_flag = domcom_protected_intimate
                    has_variable = domcom_protected_intimate_patron
                    var:domcom_protected_intimate_patron = scope:domcom_jealousy_patron
                }
            }
            OR = {
                has_relation_lover = scope:domcom_jealousy_patron
                has_relation_soulmate = scope:domcom_jealousy_patron
            }
        }
        random = {
            chance = $CHANCE$
            if = { limit = { has_relation_soulmate = scope:domcom_jealousy_patron } remove_relation_soulmate = scope:domcom_jealousy_patron }
            if = { limit = { has_relation_lover = scope:domcom_jealousy_patron } remove_relation_lover = scope:domcom_jealousy_patron }
            remove_character_flag = domcom_communion_intimate_bound
            if = { limit = { has_variable = domcom_communion_intimate_patron } remove_variable = domcom_communion_intimate_patron }
            scope:domcom_jealousy_patron = {
                remove_list_variable = { name = domcom_intimate_registry target = prev }
                if = { limit = { is_ai = no } trigger_event = { id = domcom_jealousy.0001 days = 2 } }
            }
        }
    }
}

domcom_jealousy_hostile_yearly_effect = {
    if = {
        limit = {
            has_character_flag = domcom_jealousy_hostile
            NOT = { has_game_rule = domcom_obedience_weight_off }
            NOT = { has_game_rule = domcom_obedience_weight_soft }
            has_variable = domcom_jealousy_target
            var:domcom_jealousy_target = { is_alive = yes }
            is_capable_adult = yes
            NOT = { any_scheme = { scheme_type = murder } }
        }
        # Reconciliation: if she has come back around, she stops being a threat.
        if = {
            limit = {
                OR = {
                    opinion = { target = var:domcom_jealousy_target value >= 0 }
                    AND = { has_variable = domcom_obedience var:domcom_obedience >= 400 }
                }
            }
            remove_character_flag = domcom_jealousy_hostile
            remove_variable = domcom_jealousy_target
            if = { limit = { has_character_modifier = domcom_jealousy_hostile_modifier } remove_character_modifier = domcom_jealousy_hostile_modifier }
        }
        else = {
            random = {
                chance = 6
                modifier = { add = 4 has_trait = vengeful }
                modifier = { add = 4 has_trait = wrathful }
                modifier = { add = 3 has_trait = deceitful }
                modifier = { add = 3 intrigue >= 14 }
                modifier = { add = -3 has_trait = forgiving }
                modifier = { add = -4 has_trait = craven }
                var:domcom_jealousy_target = { save_temporary_scope_as = domcom_jealousy_mark }
                start_scheme = { type = murder target_character = scope:domcom_jealousy_mark }
            }
            # Rarer still, and uglier: the newcomer's children by the Patron.
            random = {
                chance = 3
                modifier = { add = 3 has_trait = vengeful }
                modifier = { add = 3 has_trait = ambitious }
                modifier = { add = -3 has_trait = compassionate }
                modifier = { add = -2 has_trait = forgiving }
                if = {
                    limit = {
                        var:domcom_jealousy_target = {
                            any_child = { is_alive = yes is_adult = yes }
                        }
                    }
                    var:domcom_jealousy_target = {
                        random_child = {
                            limit = { is_alive = yes is_adult = yes }
                            save_temporary_scope_as = domcom_jealousy_mark
                        }
                    }
                    if = {
                        limit = { exists = scope:domcom_jealousy_mark }
                        start_scheme = { type = murder target_character = scope:domcom_jealousy_mark }
                    }
                }
            }
        }
    }
}


domcom_cleanup_cucked_display_modifier_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_cucked_display_modifier_cleanup_102 } }
        if = {
            limit = { has_global_variable_list = domcom_all_cucked }
            every_in_global_list = {
                variable = domcom_all_cucked
                limit = { is_alive = yes }
                remove_character_modifier = domcom_cucked_modifier
            }
        }
        set_global_variable = domcom_cucked_display_modifier_cleanup_102
    }
}

domcom_migrate_cuck_stigma_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_cuck_trait_migration_111 } }
        every_living_character = {
            limit = {
                has_character_flag = domcom_cucked
                NOT = { has_trait = domcom_cucked_trait }
            }
            add_trait = domcom_cucked_trait
        }
        domcom_prune_cuck_registry_effect = yes
        set_global_variable = domcom_cuck_trait_migration_111
    }
}

domcom_prune_cuck_registry_effect = {
    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = { NOT = { is_alive = yes } }
            save_temporary_scope_as = domcom_dead_cuck
            remove_list_global_variable = { name = domcom_all_cucked target = scope:domcom_dead_cuck }
        }
    }
}


# ---------------------------------------------------------------------------
# 2.0 — LICK THE TIP: lazy, sortable loyalty ledger
# ---------------------------------------------------------------------------
# The loyalty test itself never persists a realm-wide list. Each tested character stores only their
# latest result/patron/role/chance/Loyalty XP. The portrait roster is reconstructed only when the player
# explicitly opens Lick the Tip, sorted into a temporary list, paged 20 at a time, and cleared on exit.

# Root = loyalty subject. Converts the old 0-25 oath counter lazily and refreshes visible/pair-facing tiers.
domcom_migrate_lick_loyalty_subject_effect = {
    if = {
        limit = { NOT = { has_variable = domcom_lick_loyalty_xp } }
        set_variable = { name = domcom_lick_loyalty_xp value = 0 }
        if = {
            limit = { has_variable = domcom_lick_oath_count }
            set_variable = { name = domcom_lick_loyalty_xp value = var:domcom_lick_oath_count }
            change_variable = { name = domcom_lick_loyalty_xp multiply = 4 }
        }
        if = {
            limit = { has_character_flag = domcom_lick_permanently_bound }
            set_variable = { name = domcom_lick_loyalty_xp value = 100 }
        }
        if = { limit = { var:domcom_lick_loyalty_xp > 100 } set_variable = { name = domcom_lick_loyalty_xp value = 100 } }
    }
    if = {
        limit = { NOT = { has_variable = domcom_lick_loyalty_patron } has_variable = domcom_lick_bound_patron }
        set_variable = { name = domcom_lick_loyalty_patron value = var:domcom_lick_bound_patron }
    }
    else_if = {
        limit = { NOT = { has_variable = domcom_lick_loyalty_patron } has_variable = domcom_lick_last_patron }
        set_variable = { name = domcom_lick_loyalty_patron value = var:domcom_lick_last_patron }
    }
    domcom_refresh_lick_loyalty_tier_effect = yes
}

# Root = loyalty subject. Tier modifiers are character-facing; opinion is pair-facing toward the stored Patron.
# Root = loyalty row; scope:domcom_ui_patron required. Prepares a one-day UI-only marker for the correct Patron.
domcom_prepare_lick_row_ui_state_effect = {
    domcom_migrate_lick_loyalty_subject_effect = yes
    remove_character_flag = domcom_lick_bound_active_recently
    if = {
        limit = {
            has_character_flag = domcom_lick_permanently_bound
            has_variable = domcom_lick_bound_patron
            var:domcom_lick_bound_patron = scope:domcom_ui_patron
        }
        add_character_flag = { flag = domcom_lick_bound_active_recently days = 1 }
    }
}

domcom_refresh_lick_loyalty_tier_effect = {
    remove_character_modifier = domcom_lick_loyalty_tier_1
    remove_character_modifier = domcom_lick_loyalty_tier_2
    remove_character_modifier = domcom_lick_loyalty_tier_3
    remove_character_modifier = domcom_lick_loyalty_tier_4
    remove_character_modifier = domcom_lick_loyalty_bound

    if = {
        limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } }
        remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_1_opinion }
        remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_2_opinion }
        remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_3_opinion }
        remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_4_opinion }
        remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_bound_opinion }
    }

    if = {
        limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp >= 100 }
        set_variable = { name = domcom_lick_loyalty_xp value = 100 }
        add_character_modifier = { modifier = domcom_lick_loyalty_bound }
        if = {
            limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } }
            add_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_bound_opinion }
        }
    }
    else_if = {
        limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp >= 75 }
        add_character_modifier = { modifier = domcom_lick_loyalty_tier_4 }
        if = { limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } } add_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_4_opinion } }
    }
    else_if = {
        limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp >= 50 }
        add_character_modifier = { modifier = domcom_lick_loyalty_tier_3 }
        if = { limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } } add_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_3_opinion } }
    }
    else_if = {
        limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp >= 25 }
        add_character_modifier = { modifier = domcom_lick_loyalty_tier_2 }
        if = { limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } } add_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_2_opinion } }
    }
    else_if = {
        limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp >= 1 }
        add_character_modifier = { modifier = domcom_lick_loyalty_tier_1 }
        if = { limit = { has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = { is_alive = yes } } add_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_1_opinion } }
    }
}

# Root = loyalty subject; scope:domcom_lick_patron required. Each successful ritual gives a variable gain.
domcom_gain_lick_loyalty_xp_effect = {
    domcom_migrate_lick_loyalty_subject_effect = yes
    set_variable = { name = domcom_lick_last_xp_gain value = 0 }

    # If a different ruler is testing this subject, their loyalty track starts separately rather than inheriting another Patron's progress.
    if = {
        limit = { has_variable = domcom_lick_loyalty_patron NOT = { var:domcom_lick_loyalty_patron = scope:domcom_lick_patron } }
        if = { limit = { var:domcom_lick_loyalty_patron = { is_alive = yes } } remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_1_opinion } }
        if = { limit = { var:domcom_lick_loyalty_patron = { is_alive = yes } } remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_2_opinion } }
        if = { limit = { var:domcom_lick_loyalty_patron = { is_alive = yes } } remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_3_opinion } }
        if = { limit = { var:domcom_lick_loyalty_patron = { is_alive = yes } } remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_tier_4_opinion } }
        if = { limit = { var:domcom_lick_loyalty_patron = { is_alive = yes } } remove_opinion = { target = var:domcom_lick_loyalty_patron modifier = domcom_lick_loyalty_bound_opinion } }
        set_variable = { name = domcom_lick_loyalty_xp value = 0 }
        set_variable = { name = domcom_lick_oath_count value = 0 }
        remove_character_flag = domcom_lick_permanently_bound
        remove_variable = domcom_lick_bound_patron
    }
    set_variable = { name = domcom_lick_loyalty_patron value = scope:domcom_lick_patron }

    random_list = {
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 3 } }
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 4 } }
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 5 } }
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 6 } }
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 7 } }
        1 = { set_variable = { name = domcom_lick_last_xp_gain value = 8 } }
    }

    # Personality/relationship changes how much genuine loyalty is gained after the public act.
    if = { limit = { has_trait = humble } change_variable = { name = domcom_lick_last_xp_gain add = 2 } }
    if = { limit = { has_trait = content } change_variable = { name = domcom_lick_last_xp_gain add = 2 } }
    if = { limit = { has_trait = trusting } change_variable = { name = domcom_lick_last_xp_gain add = 1 } }
    if = { limit = { has_trait = ambitious } change_variable = { name = domcom_lick_last_xp_gain subtract = 2 } }
    if = { limit = { has_trait = arrogant } change_variable = { name = domcom_lick_last_xp_gain subtract = 2 } }
    if = { limit = { has_trait = stubborn } change_variable = { name = domcom_lick_last_xp_gain subtract = 2 } }
    if = { limit = { has_trait = brave } change_variable = { name = domcom_lick_last_xp_gain subtract = 1 } }
    if = { limit = { has_trait = craven scope:domcom_lick_patron.dread >= 40 } change_variable = { name = domcom_lick_last_xp_gain subtract = 2 } }

    if = { limit = { opinion = { target = scope:domcom_lick_patron value >= 50 } } change_variable = { name = domcom_lick_last_xp_gain add = 2 } }
    else_if = { limit = { opinion = { target = scope:domcom_lick_patron value >= 25 } } change_variable = { name = domcom_lick_last_xp_gain add = 1 } }
    else_if = { limit = { opinion = { target = scope:domcom_lick_patron value <= -50 } } change_variable = { name = domcom_lick_last_xp_gain subtract = 2 } }
    else_if = { limit = { opinion = { target = scope:domcom_lick_patron value <= -25 } } change_variable = { name = domcom_lick_last_xp_gain subtract = 1 } }

    if = { limit = { has_relation_soulmate = scope:domcom_lick_patron } change_variable = { name = domcom_lick_last_xp_gain add = 4 } }
    else_if = { limit = { has_relation_lover = scope:domcom_lick_patron } change_variable = { name = domcom_lick_last_xp_gain add = 2 } }
    if = { limit = { has_character_flag = domcom_owned_cuck has_variable = domcom_patron var:domcom_patron = scope:domcom_lick_patron } change_variable = { name = domcom_lick_last_xp_gain add = 3 } }
    else_if = { limit = { has_character_flag = domcom_cucked has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_lick_patron } change_variable = { name = domcom_lick_last_xp_gain add = 2 } }

    if = { limit = { var:domcom_lick_last_xp_gain < 1 } set_variable = { name = domcom_lick_last_xp_gain value = 1 } }
    if = { limit = { var:domcom_lick_last_xp_gain > 15 } set_variable = { name = domcom_lick_last_xp_gain value = 15 } }
    change_variable = { name = domcom_lick_loyalty_xp add = var:domcom_lick_last_xp_gain }
    if = { limit = { var:domcom_lick_loyalty_xp > 100 } set_variable = { name = domcom_lick_loyalty_xp value = 100 } }

    # Keep the old oath counter as a derived compatibility value for older saves/scripts.
    set_variable = { name = domcom_lick_oath_count value = var:domcom_lick_loyalty_xp }
    change_variable = { name = domcom_lick_oath_count divide = 4 }
    if = { limit = { var:domcom_lick_oath_count > 25 } set_variable = { name = domcom_lick_oath_count value = 25 } }

    if = {
        limit = { var:domcom_lick_loyalty_xp >= 100 }
        set_variable = { name = domcom_lick_loyalty_xp value = 100 }
        set_variable = { name = domcom_lick_oath_count value = 25 }
        add_character_flag = domcom_lick_permanently_bound
        add_character_flag = { flag = domcom_lick_bound_active_recently years = 1 }
        set_variable = { name = domcom_lick_bound_patron value = scope:domcom_lick_patron }
    }
    domcom_refresh_lick_loyalty_tier_effect = yes
}

# Root = tested character; scope:domcom_lick_patron = ruler calling the test.
domcom_resolve_lick_subject_effect = {
    set_variable = { name = domcom_lick_last_patron value = scope:domcom_lick_patron }
    domcom_migrate_lick_loyalty_subject_effect = yes
    set_variable = { name = domcom_lick_last_chance value = domcom_lick_loyalty_chance_value }
    remove_character_flag = domcom_lick_complied_recently
    remove_character_flag = domcom_lick_refused_recently
    remove_character_flag = domcom_lick_bound_active_recently

    # A fully Bound subject of this Patron no longer rolls: the political oath has become automatic.
    if = {
        limit = {
            has_character_flag = domcom_lick_permanently_bound
            has_variable = domcom_lick_bound_patron
            var:domcom_lick_bound_patron = scope:domcom_lick_patron
        }
        set_variable = { name = domcom_lick_last_chance value = 100 }
        set_variable = { name = domcom_lick_last_result value = 1 }
        set_variable = { name = domcom_lick_last_xp_gain value = 0 }
        add_character_flag = { flag = domcom_lick_complied_recently years = 1 }
        add_character_flag = { flag = domcom_lick_bound_active_recently years = 1 }
        remove_character_flag = domcom_lick_refusal_defiance
        scope:domcom_lick_patron = { change_variable = { name = domcom_lick_complied_count add = 1 } }
    }
    else = {
        random = {
            chance = var:domcom_lick_last_chance
            set_variable = { name = domcom_lick_last_result value = 1 }
            add_character_flag = { flag = domcom_lick_complied_recently years = 1 }
            remove_character_flag = domcom_lick_refusal_defiance
            scope:domcom_lick_patron = { change_variable = { name = domcom_lick_complied_count add = 1 } }
        }
        if = {
            limit = { NOT = { has_character_flag = domcom_lick_complied_recently } }
            set_variable = { name = domcom_lick_last_result value = 0 }
            set_variable = { name = domcom_lick_last_xp_gain value = 0 }
            add_character_flag = { flag = domcom_lick_refused_recently years = 1 }
            add_character_flag = { flag = domcom_lick_refusal_defiance months = 4 }
            scope:domcom_lick_patron = { change_variable = { name = domcom_lick_refused_count add = 1 } }
            if = {
                limit = { has_variable = domcom_lick_role var:domcom_lick_role = 2 }
                scope:domcom_lick_patron = { change_variable = { name = domcom_lick_vassal_refused_count add = 1 } }
            }
            else = {
                scope:domcom_lick_patron = { change_variable = { name = domcom_lick_courtier_refused_count add = 1 } }
            }
        }
    }

    if = {
        limit = { has_character_flag = domcom_lick_complied_recently NOT = { has_character_flag = domcom_lick_permanently_bound } }
        domcom_gain_lick_loyalty_xp_effect = yes
    }
    if = {
        limit = { has_character_flag = domcom_lick_complied_recently }
        domcom_register_cult_adherent_effect = yes
    }
}

# Run the realm-wide test without constructing a persistent portrait roster.
domcom_call_lick_test_effect = {
    save_scope_as = domcom_lick_patron
    clear_variable_list = domcom_ui_lick_raw
    clear_variable_list = domcom_ui_lick_subjects
    clear_variable_list = domcom_lick_page_list
    set_variable = { name = domcom_lick_total_count value = 0 }
    set_variable = { name = domcom_lick_complied_count value = 0 }
    set_variable = { name = domcom_lick_refused_count value = 0 }
    set_variable = { name = domcom_lick_vassal_refused_count value = 0 }
    set_variable = { name = domcom_lick_courtier_refused_count value = 0 }

    # Temporary de-duplication only for this effect invocation.
    every_courtier = {
        limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } NOT = { is_in_list = domcom_lick_test_seen } }
        add_to_temporary_list = domcom_lick_test_seen
        set_variable = { name = domcom_lick_role value = 1 }
        scope:domcom_lick_patron = { change_variable = { name = domcom_lick_total_count add = 1 } }
        domcom_resolve_lick_subject_effect = yes
    }

    every_vassal = {
        if = {
            limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } NOT = { is_in_list = domcom_lick_test_seen } }
            add_to_temporary_list = domcom_lick_test_seen
            set_variable = { name = domcom_lick_role value = 2 }
            scope:domcom_lick_patron = { change_variable = { name = domcom_lick_total_count add = 1 } }
            domcom_resolve_lick_subject_effect = yes
        }
        every_courtier = {
            limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } NOT = { is_in_list = domcom_lick_test_seen } }
            add_to_temporary_list = domcom_lick_test_seen
            set_variable = { name = domcom_lick_role value = 3 }
            scope:domcom_lick_patron = { change_variable = { name = domcom_lick_total_count add = 1 } }
            domcom_resolve_lick_subject_effect = yes
        }
    }

    # Public obedience changes the Patron's reputation according to how much of the realm complied.
    if = { limit = { var:domcom_lick_complied_count >= 25 } domcom_rep_gain_overlord_major_effect = yes }
    else_if = { limit = { var:domcom_lick_complied_count >= 5 } domcom_rep_gain_overlord_small_effect = yes }

    # Three calls per year at most: four-month cooldown rather than a 25-year annual grind.
    add_character_flag = { flag = domcom_lick_test_cooldown months = 4 }
    add_character_flag = domcom_lick_has_results
    domcom_refresh_cult_ui_only_effect = yes
    # Lick remains dynamic: apply the new Devoted target immediately when safe, otherwise queue it.
    domcom_reconcile_devoted_retinue_effect = yes
    send_interface_toast = { type = event_toast_effect_neutral title = DOMCOM_LICK_TEST_TOAST left_icon = root }
}

# Lazily reconstruct only current realm members whose latest stored Lick result belongs to this Patron.
# The roster remains lazy and does not depend on the four-month cooldown flag, so last results remain inspectable.
domcom_prepare_lick_page_safe_effect = {
    domcom_refresh_cult_ui_only_effect = yes
    domcom_clear_ui_raw_roster_caches_effect = yes
    save_scope_as = domcom_ui_patron
    clear_variable_list = domcom_ui_lick_raw
    clear_variable_list = domcom_ui_lick_subjects
    clear_variable_list = domcom_lick_page_list
    set_variable = { name = domcom_ui_lick_page value = 0 }

    if = { limit = { NOT = { exists = var:domcom_ui_lick_sort_mode } } set_variable = { name = domcom_ui_lick_sort_mode value = flag:status } }
    if = { limit = { NOT = { exists = var:domcom_ui_lick_sort_direction } } set_variable = { name = domcom_ui_lick_sort_direction value = flag:descending } }

    every_courtier = {
        limit = {
            is_alive = yes age >= 18
            NOT = { this = scope:domcom_ui_patron }
            has_variable = domcom_lick_last_patron
            var:domcom_lick_last_patron = scope:domcom_ui_patron
            has_variable = domcom_lick_last_result
            NOT = { is_in_list = domcom_lick_roster_seen }
        }
        add_to_temporary_list = domcom_lick_roster_seen
        domcom_prepare_lick_row_ui_state_effect = yes
        save_temporary_scope_as = domcom_lick_row
        scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_raw target = scope:domcom_lick_row } }
    }
    every_vassal = {
        if = {
            limit = {
                is_alive = yes age >= 18
                NOT = { this = scope:domcom_ui_patron }
                has_variable = domcom_lick_last_patron
                var:domcom_lick_last_patron = scope:domcom_ui_patron
                has_variable = domcom_lick_last_result
                NOT = { is_in_list = domcom_lick_roster_seen }
            }
            add_to_temporary_list = domcom_lick_roster_seen
            domcom_prepare_lick_row_ui_state_effect = yes
            save_temporary_scope_as = domcom_lick_row
            scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_raw target = scope:domcom_lick_row } }
        }
        every_courtier = {
            limit = {
                is_alive = yes age >= 18
                NOT = { this = scope:domcom_ui_patron }
                has_variable = domcom_lick_last_patron
                var:domcom_lick_last_patron = scope:domcom_ui_patron
                has_variable = domcom_lick_last_result
                NOT = { is_in_list = domcom_lick_roster_seen }
            }
            add_to_temporary_list = domcom_lick_roster_seen
            domcom_prepare_lick_row_ui_state_effect = yes
            save_temporary_scope_as = domcom_lick_row
            scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_raw target = scope:domcom_lick_row } }
        }
    }
    domcom_rebuild_lick_roster_effect = yes
}

domcom_rebuild_lick_roster_effect = {
    clear_variable_list = domcom_ui_lick_subjects
    clear_variable_list = domcom_lick_page_list
    save_scope_as = domcom_ui_patron
    if = {
        limit = { has_variable_list = domcom_ui_lick_raw }
        if = { limit = { var:domcom_ui_lick_sort_mode = flag:oaths } domcom_order_lick_oaths_effect = yes }
        else_if = { limit = { var:domcom_ui_lick_sort_mode = flag:rank } domcom_order_lick_rank_effect = yes }
        else_if = { limit = { var:domcom_ui_lick_sort_mode = flag:chance } domcom_order_lick_chance_effect = yes }
        else_if = { limit = { var:domcom_ui_lick_sort_mode = flag:opinion } domcom_order_lick_opinion_effect = yes }
        else_if = { limit = { var:domcom_ui_lick_sort_mode = flag:obedience } domcom_order_lick_obedience_effect = yes }
        else_if = { limit = { var:domcom_ui_lick_sort_mode = flag:xp } domcom_order_lick_xp_effect = yes }
        else = { domcom_order_lick_status_effect = yes }
    }
    domcom_build_lick_page_effect = yes
}

# Descending is the natural/default direction. Status intentionally puts refusers first and then sorts
# within each result group by Loyalty XP, matching the page's default investigative use.
domcom_order_lick_status_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_lick_status_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = {
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_lick_status_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    }
}
domcom_order_lick_oaths_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_lick_oath_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_lick_oath_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}
domcom_order_lick_rank_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_sort_rank_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_sort_rank_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}
domcom_order_lick_chance_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_lick_chance_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_lick_chance_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}
domcom_order_lick_opinion_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_lick_opinion_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_lick_opinion_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}
domcom_order_lick_obedience_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_lick_obedience_sort_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_lick_obedience_sort_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}
domcom_order_lick_xp_effect = {
    if = { limit = { var:domcom_ui_lick_sort_direction = flag:ascending }
        ordered_in_list = { variable = domcom_ui_lick_raw order_by = { value = domcom_sort_xp_value multiply = -1 } max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } }
    } else = { ordered_in_list = { variable = domcom_ui_lick_raw order_by = domcom_sort_xp_value max = 100000 check_range_bounds = no save_temporary_scope_as = domcom_lick_sorted scope:domcom_ui_patron = { add_to_variable_list = { name = domcom_ui_lick_subjects target = scope:domcom_lick_sorted } } } }
}

domcom_build_lick_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_lick_page } } set_variable = { name = domcom_ui_lick_page value = 0 } }
    clear_variable_list = domcom_lick_page_list
    set_variable = { name = domcom_ui_lick_total value = 0 }
    set_variable = { name = domcom_ui_lick_last_page value = 0 }
    set_variable = { name = domcom_ui_lick_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_lick_subjects }
        every_in_list = {
            variable = domcom_ui_lick_subjects
            prev = {
                if = { limit = { var:domcom_ui_lick_page_fill >= var:domcom_ui_standard_page_size } change_variable = { name = domcom_ui_lick_last_page add = 1 } set_variable = { name = domcom_ui_lick_page_fill value = 0 } }
                change_variable = { name = domcom_ui_lick_page_fill add = 1 }
                change_variable = { name = domcom_ui_lick_total add = 1 }
            }
        }
    }
    if = { limit = { var:domcom_ui_lick_page < 0 } set_variable = { name = domcom_ui_lick_page value = 0 } }
    if = { limit = { var:domcom_ui_lick_page > var:domcom_ui_lick_last_page } set_variable = { name = domcom_ui_lick_page value = var:domcom_ui_lick_last_page } }
    set_variable = { name = domcom_ui_lick_first value = var:domcom_ui_lick_page }
    change_variable = { name = domcom_ui_lick_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_lick_stop value = var:domcom_ui_lick_first }
    change_variable = { name = domcom_ui_lick_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_lick_index value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_lick_subjects }
        every_in_list = {
            variable = domcom_ui_lick_subjects
            save_temporary_scope_as = domcom_lick_page_row
            prev = {
                if = { limit = { var:domcom_ui_lick_index >= var:domcom_ui_lick_first var:domcom_ui_lick_index < var:domcom_ui_lick_stop } add_to_variable_list = { name = domcom_lick_page_list target = scope:domcom_lick_page_row } }
                change_variable = { name = domcom_ui_lick_index add = 1 }
            }
        }
    }
    set_variable = { name = domcom_ui_lick_shown_from value = var:domcom_ui_lick_first }
    change_variable = { name = domcom_ui_lick_shown_from add = 1 }
    set_variable = { name = domcom_ui_lick_shown_to value = var:domcom_ui_lick_stop }
    if = { limit = { var:domcom_ui_lick_shown_to > var:domcom_ui_lick_total } set_variable = { name = domcom_ui_lick_shown_to value = var:domcom_ui_lick_total } }
    set_variable = { name = domcom_ui_lick_page_display value = var:domcom_ui_lick_page }
    change_variable = { name = domcom_ui_lick_page_display add = 1 }
    set_variable = { name = domcom_ui_lick_pages_display value = var:domcom_ui_lick_last_page }
    change_variable = { name = domcom_ui_lick_pages_display add = 1 }
    if = { limit = { var:domcom_ui_lick_total = 0 } set_variable = { name = domcom_ui_lick_shown_from value = 0 } }
}



# ---------------------------------------------------------------------------
# 2.0 — LICK THE TIP: Cult of Personality economy and The Devoted retinue
# ---------------------------------------------------------------------------
# Root = successful Lick subject; scope:domcom_lick_patron is the ruler. A subject is registered once
# per current Patron. Stale old-Patron entries are pruned by the Patron's monthly maintenance pass.
domcom_register_cult_adherent_effect = {
    save_temporary_scope_as = domcom_cult_registering_subject
    # Never trust the subject-side cache as proof that the Patron list still contains this character.
    # Remove any stale membership, then re-add exactly once to the current Patron.
    if = {
        limit = { has_variable = domcom_lick_cult_registered_patron var:domcom_lick_cult_registered_patron = { is_alive = yes } }
        var:domcom_lick_cult_registered_patron = {
            if = { limit = { has_variable_list = domcom_lick_cult_adherents } remove_list_variable = { name = domcom_lick_cult_adherents target = scope:domcom_cult_registering_subject } }
        }
    }
    set_variable = { name = domcom_lick_cult_registered_patron value = scope:domcom_lick_patron }
    scope:domcom_lick_patron = {
        if = { limit = { has_variable_list = domcom_lick_cult_adherents } remove_list_variable = { name = domcom_lick_cult_adherents target = scope:domcom_cult_registering_subject } }
        add_to_variable_list = { name = domcom_lick_cult_adherents target = scope:domcom_cult_registering_subject }
    }
}

# Root = Patron. One-time bounded recovery for saves that already had Lick progress before the cult list existed.
# It scans only the Patron's current court, direct vassals and their courts — never the world.
domcom_recover_existing_cult_adherents_once_effect = {
    if = {
        limit = { NOT = { has_character_flag = domcom_cult_adherents_recovered_200 } }
        save_scope_as = domcom_lick_patron
        every_courtier = {
            limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } }
            domcom_migrate_lick_loyalty_subject_effect = yes
            if = { limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp > 0 has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = scope:domcom_lick_patron } domcom_register_cult_adherent_effect = yes }
        }
        every_vassal = {
            if = {
                limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } }
                domcom_migrate_lick_loyalty_subject_effect = yes
                if = { limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp > 0 has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = scope:domcom_lick_patron } domcom_register_cult_adherent_effect = yes }
            }
            every_courtier = {
                limit = { is_alive = yes age >= 18 NOT = { this = scope:domcom_lick_patron } }
                domcom_migrate_lick_loyalty_subject_effect = yes
                if = { limit = { has_variable = domcom_lick_loyalty_xp var:domcom_lick_loyalty_xp > 0 has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = scope:domcom_lick_patron } domcom_register_cult_adherent_effect = yes }
            }
        }
        add_character_flag = domcom_cult_adherents_recovered_200
    }
}

# Root = Patron. Rebuild aggregate values from the bounded persistent adherent list without touching UI portrait caches.
domcom_refresh_cult_of_personality_effect = {
    save_scope_as = domcom_cult_patron
    set_variable = { name = domcom_cult_adherent_count value = 0 }
    set_variable = { name = domcom_cult_bound_count value = 0 }
    set_variable = { name = domcom_cult_total_xp value = 0 }
    set_variable = { name = domcom_cult_strength value = 0 }

    if = {
        limit = { has_variable_list = domcom_lick_cult_adherents }
        # Prune dead/transferred records first.
        every_in_list = {
            variable = domcom_lick_cult_adherents
            limit = { OR = { is_alive = no NOT = { has_variable = domcom_lick_loyalty_patron } NOT = { var:domcom_lick_loyalty_patron = scope:domcom_cult_patron } } }
            save_temporary_scope_as = domcom_stale_cult_adherent
            scope:domcom_cult_patron = { remove_list_variable = { name = domcom_lick_cult_adherents target = scope:domcom_stale_cult_adherent } }
        }
        every_in_list = {
            variable = domcom_lick_cult_adherents
            limit = { is_alive = yes has_variable = domcom_lick_loyalty_patron var:domcom_lick_loyalty_patron = scope:domcom_cult_patron }
            domcom_migrate_lick_loyalty_subject_effect = yes
            save_temporary_scope_as = domcom_counted_cult_adherent
            scope:domcom_cult_patron = {
                change_variable = { name = domcom_cult_adherent_count add = 1 }
                change_variable = { name = domcom_cult_strength add = 0.25 }
                change_variable = { name = domcom_cult_total_xp add = scope:domcom_counted_cult_adherent.var:domcom_lick_loyalty_xp }
            }
            # Social importance makes a ruler's public submission worth more than an obscure courtier's.
            if = { limit = { is_landed = yes highest_held_title_tier = tier_county } scope:domcom_cult_patron = { change_variable = { name = domcom_cult_strength add = 0.15 } } }
            else_if = { limit = { is_landed = yes highest_held_title_tier = tier_duchy } scope:domcom_cult_patron = { change_variable = { name = domcom_cult_strength add = 0.30 } } }
            else_if = { limit = { is_landed = yes highest_held_title_tier = tier_kingdom } scope:domcom_cult_patron = { change_variable = { name = domcom_cult_strength add = 0.60 } } }
            else_if = { limit = { is_landed = yes OR = { highest_held_title_tier = tier_empire highest_held_title_tier = tier_hegemony } } scope:domcom_cult_patron = { change_variable = { name = domcom_cult_strength add = 1.00 } } }
            if = { limit = { has_character_flag = domcom_lick_permanently_bound has_variable = domcom_lick_bound_patron var:domcom_lick_bound_patron = scope:domcom_cult_patron } scope:domcom_cult_patron = { change_variable = { name = domcom_cult_bound_count add = 1 } change_variable = { name = domcom_cult_strength add = 0.50 } } }
        }
    }

    # Loyalty itself supplies the other half of cult strength.
    set_variable = { name = domcom_cult_xp_strength value = var:domcom_cult_total_xp }
    change_variable = { name = domcom_cult_xp_strength divide = 100 }
    change_variable = { name = domcom_cult_strength add = var:domcom_cult_xp_strength }
    set_variable = { name = domcom_cult_average_loyalty value = 0 }
    if = { limit = { var:domcom_cult_adherent_count > 0 } set_variable = { name = domcom_cult_average_loyalty value = var:domcom_cult_total_xp } change_variable = { name = domcom_cult_average_loyalty divide = var:domcom_cult_adherent_count } }

    # Monthly tribute estimates and actual payments. 2.1.1 uses rounded whole-number
    # outputs and caps them so a giant late-game cult remains powerful without becoming
    # an unlimited currency printer. Piety is now part of the cult economy as well.
    set_variable = { name = domcom_cult_monthly_gold value = domcom_cult_monthly_gold_value }
    set_variable = { name = domcom_cult_monthly_prestige value = domcom_cult_monthly_prestige_value }
    set_variable = { name = domcom_cult_monthly_piety value = domcom_cult_monthly_piety_value }
    set_variable = { name = domcom_cult_monthly_renown value = domcom_cult_monthly_renown_value }
    set_variable = { name = domcom_cult_monthly_legitimacy value = domcom_cult_monthly_legitimacy_value }

    # Gold, Prestige, Piety and Renown are now genuine monthly modifiers, so their contributions appear
    # in the standard resource hover breakdown. Legitimacy has no equivalent generic monthly modifier
    # in this scripting surface and therefore remains the one direct monthly payment.
    domcom_refresh_cult_resource_modifiers_effect = yes
    if = { limit = { var:domcom_cult_adherent_count > 0 NOT = { has_character_flag = domcom_cult_refresh_only } is_landed = yes has_legitimacy = yes }
        add_legitimacy = var:domcom_cult_monthly_legitimacy
    }

    # 100 unique active adherents permanently establishes this ruler's Cult of Personality milestone.
    # The economic/retinue output still follows living adherents, but the personal threshold reward does
    # not vanish because followers later die. It is not inherited by the next ruler.
    if = { limit = { var:domcom_cult_adherent_count >= 100 } add_character_flag = domcom_cult_hundred_reached }
    remove_character_modifier = domcom_cult_hundred_voices
    if = {
        limit = { has_character_flag = domcom_cult_hundred_reached }
        add_character_modifier = { modifier = domcom_cult_hundred_voices }
        # Native ruler modifiers provide +45% legitimacy gain and +45% owned-legend spread.
    }

    # Military state is intentionally NOT reconciled here. Aggregate/cult state can update at any
    # frequency, including GUI refreshes, without destroying or recreating an active regiment.
    domcom_compute_devoted_retinue_target_effect = yes
}

# Root = Patron. Recompute cult/UI state only. This path must never physically alter Men-at-Arms.
domcom_refresh_cult_ui_only_effect = {
    add_character_flag = domcom_cult_refresh_only
    domcom_recover_existing_cult_adherents_once_effect = yes
    domcom_refresh_cult_of_personality_effect = yes
    remove_character_flag = domcom_cult_refresh_only
}

# Root = Patron. Compute the cult-supported Devoted configuration. This is pure state calculation:
# it is safe to run from GUI refreshes and never destroys, creates, or resizes a regiment.
domcom_compute_devoted_retinue_target_effect = {
    set_variable = { name = domcom_cult_desired_size value = 0 }
    if = { limit = { var:domcom_cult_adherent_count >= 5 } set_variable = { name = domcom_cult_desired_size value = 1 } }
    if = { limit = { var:domcom_cult_adherent_count >= 15 } set_variable = { name = domcom_cult_desired_size value = 2 } }
    if = { limit = { var:domcom_cult_adherent_count >= 30 } set_variable = { name = domcom_cult_desired_size value = 3 } }
    if = { limit = { var:domcom_cult_adherent_count >= 50 } set_variable = { name = domcom_cult_desired_size value = 5 } }
    if = { limit = { var:domcom_cult_adherent_count >= 75 } set_variable = { name = domcom_cult_desired_size value = 7 } }
    if = { limit = { var:domcom_cult_adherent_count >= 100 } set_variable = { name = domcom_cult_desired_size value = 10 } }
    if = { limit = { var:domcom_cult_adherent_count >= 150 } set_variable = { name = domcom_cult_desired_size value = 15 } }
    if = { limit = { var:domcom_cult_adherent_count >= 250 } set_variable = { name = domcom_cult_desired_size value = 25 } }
    if = { limit = { var:domcom_cult_adherent_count >= 400 } set_variable = { name = domcom_cult_desired_size value = 40 } }

    set_variable = { name = domcom_cult_desired_quality value = 1 }
    if = { limit = { var:domcom_cult_average_loyalty >= 25 } set_variable = { name = domcom_cult_desired_quality value = 2 } }
    if = { limit = { var:domcom_cult_average_loyalty >= 50 } set_variable = { name = domcom_cult_desired_quality value = 3 } }
    if = { limit = { var:domcom_cult_average_loyalty >= 75 } set_variable = { name = domcom_cult_desired_quality value = 4 } }

    # Pending is a deployment state, not a cult-state delay. The cult changes immediately; only the
    # physical regiment waits until it is safe to reconcile.
    set_variable = { name = domcom_cult_retinue_pending value = 0 }
    if = {
        limit = {
            OR = {
                NOT = { has_variable = domcom_cult_retinue_size }
                NOT = { has_variable = domcom_cult_retinue_quality }
                var:domcom_cult_retinue_size != var:domcom_cult_desired_size
                var:domcom_cult_retinue_quality != var:domcom_cult_desired_quality
                AND = {
                    var:domcom_cult_desired_size > 0
                    NOT = {
                        any_maa_regiment = {
                            OR = { is_maa_type = domcom_devoted_mob_1 is_maa_type = domcom_devoted_mob_1_2 is_maa_type = domcom_devoted_mob_1_3 is_maa_type = domcom_devoted_mob_1_5 is_maa_type = domcom_devoted_mob_1_7 is_maa_type = domcom_devoted_mob_1_10 is_maa_type = domcom_devoted_mob_1_15 is_maa_type = domcom_devoted_mob_1_25 is_maa_type = domcom_devoted_mob_1_40 is_maa_type = domcom_devoted_mob_2 is_maa_type = domcom_devoted_mob_2_2 is_maa_type = domcom_devoted_mob_2_3 is_maa_type = domcom_devoted_mob_2_5 is_maa_type = domcom_devoted_mob_2_7 is_maa_type = domcom_devoted_mob_2_10 is_maa_type = domcom_devoted_mob_2_15 is_maa_type = domcom_devoted_mob_2_25 is_maa_type = domcom_devoted_mob_2_40 is_maa_type = domcom_devoted_mob_3 is_maa_type = domcom_devoted_mob_3_2 is_maa_type = domcom_devoted_mob_3_3 is_maa_type = domcom_devoted_mob_3_5 is_maa_type = domcom_devoted_mob_3_7 is_maa_type = domcom_devoted_mob_3_10 is_maa_type = domcom_devoted_mob_3_15 is_maa_type = domcom_devoted_mob_3_25 is_maa_type = domcom_devoted_mob_3_40 is_maa_type = domcom_devoted_mob_4 is_maa_type = domcom_devoted_mob_4_2 is_maa_type = domcom_devoted_mob_4_3 is_maa_type = domcom_devoted_mob_4_5 is_maa_type = domcom_devoted_mob_4_7 is_maa_type = domcom_devoted_mob_4_10 is_maa_type = domcom_devoted_mob_4_15 is_maa_type = domcom_devoted_mob_4_25 is_maa_type = domcom_devoted_mob_4_40 }
                        }
                    }
                }
                AND = {
                    var:domcom_cult_desired_size = 0
                    any_maa_regiment = {
                        OR = { is_maa_type = domcom_devoted_mob_1 is_maa_type = domcom_devoted_mob_1_2 is_maa_type = domcom_devoted_mob_1_3 is_maa_type = domcom_devoted_mob_1_5 is_maa_type = domcom_devoted_mob_1_7 is_maa_type = domcom_devoted_mob_1_10 is_maa_type = domcom_devoted_mob_1_15 is_maa_type = domcom_devoted_mob_1_25 is_maa_type = domcom_devoted_mob_1_40 is_maa_type = domcom_devoted_mob_2 is_maa_type = domcom_devoted_mob_2_2 is_maa_type = domcom_devoted_mob_2_3 is_maa_type = domcom_devoted_mob_2_5 is_maa_type = domcom_devoted_mob_2_7 is_maa_type = domcom_devoted_mob_2_10 is_maa_type = domcom_devoted_mob_2_15 is_maa_type = domcom_devoted_mob_2_25 is_maa_type = domcom_devoted_mob_2_40 is_maa_type = domcom_devoted_mob_3 is_maa_type = domcom_devoted_mob_3_2 is_maa_type = domcom_devoted_mob_3_3 is_maa_type = domcom_devoted_mob_3_5 is_maa_type = domcom_devoted_mob_3_7 is_maa_type = domcom_devoted_mob_3_10 is_maa_type = domcom_devoted_mob_3_15 is_maa_type = domcom_devoted_mob_3_25 is_maa_type = domcom_devoted_mob_3_40 is_maa_type = domcom_devoted_mob_4 is_maa_type = domcom_devoted_mob_4_2 is_maa_type = domcom_devoted_mob_4_3 is_maa_type = domcom_devoted_mob_4_5 is_maa_type = domcom_devoted_mob_4_7 is_maa_type = domcom_devoted_mob_4_10 is_maa_type = domcom_devoted_mob_4_15 is_maa_type = domcom_devoted_mob_4_25 is_maa_type = domcom_devoted_mob_4_40 }
                    }
                }
            }
        }
        set_variable = { name = domcom_cult_retinue_pending value = 1 }
    }
}

# Root = Patron. Apply the pending Devoted configuration only when no army is raised/gathering.
# This is the ONLY effect allowed to destroy/recreate the cult regiment.
domcom_reconcile_devoted_retinue_effect = {
    domcom_compute_devoted_retinue_target_effect = yes
    if = {
        limit = { has_raised_armies = no var:domcom_cult_retinue_pending = 1 }

        # The Cult regiment receives its own roster slot so it does not displace ordinary MAA.
        remove_character_modifier = domcom_cult_retinue_slot
        if = { limit = { var:domcom_cult_desired_size > 0 } add_character_modifier = { modifier = domcom_cult_retinue_slot } }

        every_maa_regiment = { limit = { OR = { is_maa_type = domcom_devoted_mob_1 is_maa_type = domcom_devoted_mob_1_2 is_maa_type = domcom_devoted_mob_1_3 is_maa_type = domcom_devoted_mob_1_5 is_maa_type = domcom_devoted_mob_1_7 is_maa_type = domcom_devoted_mob_1_10 is_maa_type = domcom_devoted_mob_1_15 is_maa_type = domcom_devoted_mob_1_25 is_maa_type = domcom_devoted_mob_1_40 is_maa_type = domcom_devoted_mob_2 is_maa_type = domcom_devoted_mob_2_2 is_maa_type = domcom_devoted_mob_2_3 is_maa_type = domcom_devoted_mob_2_5 is_maa_type = domcom_devoted_mob_2_7 is_maa_type = domcom_devoted_mob_2_10 is_maa_type = domcom_devoted_mob_2_15 is_maa_type = domcom_devoted_mob_2_25 is_maa_type = domcom_devoted_mob_2_40 is_maa_type = domcom_devoted_mob_3 is_maa_type = domcom_devoted_mob_3_2 is_maa_type = domcom_devoted_mob_3_3 is_maa_type = domcom_devoted_mob_3_5 is_maa_type = domcom_devoted_mob_3_7 is_maa_type = domcom_devoted_mob_3_10 is_maa_type = domcom_devoted_mob_3_15 is_maa_type = domcom_devoted_mob_3_25 is_maa_type = domcom_devoted_mob_3_40 is_maa_type = domcom_devoted_mob_4 is_maa_type = domcom_devoted_mob_4_2 is_maa_type = domcom_devoted_mob_4_3 is_maa_type = domcom_devoted_mob_4_5 is_maa_type = domcom_devoted_mob_4_7 is_maa_type = domcom_devoted_mob_4_10 is_maa_type = domcom_devoted_mob_4_15 is_maa_type = domcom_devoted_mob_4_25 is_maa_type = domcom_devoted_mob_4_40 } } destroy_maa_regiment = yes }
        set_variable = { name = domcom_cult_retinue_size value = var:domcom_cult_desired_size }
        set_variable = { name = domcom_cult_retinue_quality value = var:domcom_cult_desired_quality }
        if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 1 } create_maa_regiment = { type = domcom_devoted_mob_1 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 2 } create_maa_regiment = { type = domcom_devoted_mob_1_2 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 3 } create_maa_regiment = { type = domcom_devoted_mob_1_3 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 5 } create_maa_regiment = { type = domcom_devoted_mob_1_5 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 7 } create_maa_regiment = { type = domcom_devoted_mob_1_7 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 10 } create_maa_regiment = { type = domcom_devoted_mob_1_10 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 15 } create_maa_regiment = { type = domcom_devoted_mob_1_15 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 25 } create_maa_regiment = { type = domcom_devoted_mob_1_25 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 1 var:domcom_cult_desired_size = 40 } create_maa_regiment = { type = domcom_devoted_mob_1_40 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 1 } create_maa_regiment = { type = domcom_devoted_mob_2 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 2 } create_maa_regiment = { type = domcom_devoted_mob_2_2 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 3 } create_maa_regiment = { type = domcom_devoted_mob_2_3 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 5 } create_maa_regiment = { type = domcom_devoted_mob_2_5 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 7 } create_maa_regiment = { type = domcom_devoted_mob_2_7 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 10 } create_maa_regiment = { type = domcom_devoted_mob_2_10 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 15 } create_maa_regiment = { type = domcom_devoted_mob_2_15 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 25 } create_maa_regiment = { type = domcom_devoted_mob_2_25 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 2 var:domcom_cult_desired_size = 40 } create_maa_regiment = { type = domcom_devoted_mob_2_40 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 1 } create_maa_regiment = { type = domcom_devoted_mob_3 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 2 } create_maa_regiment = { type = domcom_devoted_mob_3_2 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 3 } create_maa_regiment = { type = domcom_devoted_mob_3_3 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 5 } create_maa_regiment = { type = domcom_devoted_mob_3_5 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 7 } create_maa_regiment = { type = domcom_devoted_mob_3_7 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 10 } create_maa_regiment = { type = domcom_devoted_mob_3_10 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 15 } create_maa_regiment = { type = domcom_devoted_mob_3_15 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 25 } create_maa_regiment = { type = domcom_devoted_mob_3_25 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 3 var:domcom_cult_desired_size = 40 } create_maa_regiment = { type = domcom_devoted_mob_3_40 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 1 } create_maa_regiment = { type = domcom_devoted_mob_4 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 2 } create_maa_regiment = { type = domcom_devoted_mob_4_2 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 3 } create_maa_regiment = { type = domcom_devoted_mob_4_3 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 5 } create_maa_regiment = { type = domcom_devoted_mob_4_5 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 7 } create_maa_regiment = { type = domcom_devoted_mob_4_7 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 10 } create_maa_regiment = { type = domcom_devoted_mob_4_10 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 15 } create_maa_regiment = { type = domcom_devoted_mob_4_15 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 25 } create_maa_regiment = { type = domcom_devoted_mob_4_25 check_can_recruit = no size = 1 } }
        else_if = { limit = { var:domcom_cult_desired_quality = 4 var:domcom_cult_desired_size = 40 } create_maa_regiment = { type = domcom_devoted_mob_4_40 check_can_recruit = no size = 1 } }

        set_variable = { name = domcom_cult_retinue_pending value = 0 }
        if = { limit = { has_character_flag = domcom_devoted_sync_retry } remove_character_flag = domcom_devoted_sync_retry }
    }
    else_if = {
        limit = {
            var:domcom_cult_retinue_pending = 1
            has_raised_armies = yes
            NOT = { has_character_flag = domcom_devoted_sync_retry }
        }
        # No global polling: only a Patron with an actually pending military change receives this tiny
        # retry. It normally applies within three days of the armies being stood down.
        add_character_flag = { flag = domcom_devoted_sync_retry days = 4 }
        trigger_event = { id = domcom_cult.900 days = 3 }
    }
}



# 2.5.12 — convert legacy variable-sized Devoted regiments into fixed script-controlled variants.
domcom_migrate_devoted_fixed_sizes_v2512_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_devoted_fixed_sizes_migrated_v2512 } }
        every_player = {
            if = {
                limit = { any_maa_regiment = { OR = { is_maa_type = domcom_devoted_mob_1 is_maa_type = domcom_devoted_mob_2 is_maa_type = domcom_devoted_mob_3 is_maa_type = domcom_devoted_mob_4 } } }
                # Mark the deployed state stale. Reconciliation waits if armies are raised.
                set_variable = { name = domcom_cult_retinue_size value = -1 }
                set_variable = { name = domcom_cult_retinue_quality value = -1 }
                set_variable = { name = domcom_cult_retinue_pending value = 1 }
                domcom_reconcile_devoted_retinue_effect = yes
            }
        }
        set_global_variable = domcom_devoted_fixed_sizes_migrated_v2512
    }
}

# Compatibility wrapper for older internal callers. Never use this from a GUI refresh path.
domcom_update_devoted_retinue_effect = {
    domcom_reconcile_devoted_retinue_effect = yes
}

# =============================================================================
# WORLD ALPHA TOURNAMENT
# =============================================================================
# Build the field from the historical evidence itself: unique living adult same-sex Patrons who appear
# on at least one Cucked record. Victims are evidence and never become entrants merely for being victims.
domcom_world_tournament_collect_entrants_effect = {
    clear_variable_list = domcom_world_tournament_entrants
    clear_variable_list = domcom_world_tournament_current
    clear_variable_list = domcom_world_tournament_next
    clear_variable_list = domcom_world_tournament_finalists
    clear_variable_list = domcom_world_tournament_bracket_current
    clear_variable_list = domcom_world_tournament_bracket_next
    set_variable = { name = domcom_world_tournament_entrant_count value = 0 }
    set_variable = { name = domcom_world_tournament_player_entered value = 0 }
    save_scope_as = domcom_world_tournament_host

    if = {
        limit = { has_global_variable_list = domcom_all_cucked }
        every_in_global_list = {
            variable = domcom_all_cucked
            limit = { is_alive = yes age >= 18 has_character_flag = domcom_cucked }
            save_temporary_scope_as = domcom_world_tournament_victim

            if = {
                limit = { has_variable_list = domcom_cuck_patrons }
                every_in_list = {
                    variable = domcom_cuck_patrons
                    limit = {
                        is_alive = yes
                        age >= 18
                        is_imprisoned = no
                        NOT = { has_character_flag = domcom_cucked }
                        NOT = { has_trait = incapable }
                        sex_same_as = scope:domcom_world_tournament_host
                        NOT = { this = scope:domcom_world_tournament_victim }
                    }
                    save_temporary_scope_as = domcom_world_tournament_candidate
                    scope:domcom_world_tournament_host = {
                        if = {
                            limit = {
                                OR = {
                                    NOT = { has_variable_list = domcom_world_tournament_entrants }
                                    NOT = { any_in_list = { variable = domcom_world_tournament_entrants this = scope:domcom_world_tournament_candidate } }
                                }
                            }
                            add_to_variable_list = { name = domcom_world_tournament_entrants target = scope:domcom_world_tournament_candidate }
                            change_variable = { name = domcom_world_tournament_entrant_count add = 1 }
                            scope:domcom_world_tournament_candidate = {
                                set_variable = { name = domcom_world_tournament_cuck_count value = 0 }
                                set_variable = { name = domcom_world_tournament_placement value = 0 }
                                set_variable = { name = domcom_world_tournament_bracket_champion value = 0 }
                                remove_character_modifier = domcom_world_tournament_bracket_champion_modifier
                                remove_character_modifier = domcom_world_tournament_top_10_modifier
                                remove_character_modifier = domcom_world_tournament_top_5_modifier
                                remove_character_modifier = domcom_world_tournament_top_1_modifier
                                remove_character_modifier = domcom_world_tournament_runner_up_modifier
                                remove_character_modifier = domcom_world_tournament_champion_modifier
                                remove_character_modifier = domcom_world_gauntlet_tier_1_modifier
                                remove_character_modifier = domcom_world_gauntlet_tier_2_modifier
                                remove_character_modifier = domcom_world_gauntlet_tier_3_modifier
                            }
                        }
                    }
                    change_variable = { name = domcom_world_tournament_cuck_count add = 1 }
                    if = {
                        limit = { this = scope:domcom_world_tournament_host }
                        scope:domcom_world_tournament_host = { set_variable = { name = domcom_world_tournament_player_entered value = 1 } }
                    }
                }
            }
            else_if = {
                limit = {
                    has_variable = domcom_cuck_origin_patron
                    var:domcom_cuck_origin_patron = {
                        is_alive = yes
                        age >= 18
                        is_imprisoned = no
                        NOT = { has_character_flag = domcom_cucked }
                        NOT = { has_trait = incapable }
                        sex_same_as = scope:domcom_world_tournament_host
                        NOT = { this = scope:domcom_world_tournament_victim }
                    }
                }
                var:domcom_cuck_origin_patron = { save_temporary_scope_as = domcom_world_tournament_candidate }
                scope:domcom_world_tournament_host = {
                    if = {
                        limit = {
                            OR = {
                                NOT = { has_variable_list = domcom_world_tournament_entrants }
                                NOT = { any_in_list = { variable = domcom_world_tournament_entrants this = scope:domcom_world_tournament_candidate } }
                            }
                        }
                        add_to_variable_list = { name = domcom_world_tournament_entrants target = scope:domcom_world_tournament_candidate }
                        change_variable = { name = domcom_world_tournament_entrant_count add = 1 }
                        scope:domcom_world_tournament_candidate = {
                            set_variable = { name = domcom_world_tournament_cuck_count value = 0 }
                            set_variable = { name = domcom_world_tournament_placement value = 0 }
                            set_variable = { name = domcom_world_tournament_bracket_champion value = 0 }
                            remove_character_modifier = domcom_world_tournament_bracket_champion_modifier
                            remove_character_modifier = domcom_world_tournament_top_10_modifier
                            remove_character_modifier = domcom_world_tournament_top_5_modifier
                            remove_character_modifier = domcom_world_tournament_top_1_modifier
                            remove_character_modifier = domcom_world_tournament_runner_up_modifier
                            remove_character_modifier = domcom_world_tournament_champion_modifier
                            remove_character_modifier = domcom_world_gauntlet_tier_1_modifier
                            remove_character_modifier = domcom_world_gauntlet_tier_2_modifier
                            remove_character_modifier = domcom_world_gauntlet_tier_3_modifier
                        }
                    }
                }
                scope:domcom_world_tournament_candidate = {
                    change_variable = { name = domcom_world_tournament_cuck_count add = 1 }
                    if = {
                        limit = { this = scope:domcom_world_tournament_host }
                        scope:domcom_world_tournament_host = { set_variable = { name = domcom_world_tournament_player_entered value = 1 } }
                    }
                }
            }
        }
    }

    # Freeze each eligible entrant's Alpha Rating only after the full cuck-record scan, because the
    # record component is accumulated while victims are traversed. Cucked and Incapable characters never enter.
    every_in_list = {
        variable = domcom_world_tournament_entrants
        set_variable = { name = domcom_world_tournament_alpha_rating value = domcom_world_tournament_seed_value }
    }

    # Tournament scale is based on the number of actual cuckers, never the number of victims.
    if = { limit = { var:domcom_world_tournament_entrant_count >= 128 } set_variable = { name = domcom_world_tournament_field_tier value = 5 } }
    else_if = { limit = { var:domcom_world_tournament_entrant_count >= 64 } set_variable = { name = domcom_world_tournament_field_tier value = 4 } }
    else_if = { limit = { var:domcom_world_tournament_entrant_count >= 32 } set_variable = { name = domcom_world_tournament_field_tier value = 3 } }
    else_if = { limit = { var:domcom_world_tournament_entrant_count >= 16 } set_variable = { name = domcom_world_tournament_field_tier value = 2 } }
    else = { set_variable = { name = domcom_world_tournament_field_tier value = 1 } }
}

# Called from a seeded-gauntlet match winner with scope:domcom_world_tournament_loser and host saved.
domcom_world_tournament_advance_winner_effect = {
    save_temporary_scope_as = domcom_world_tournament_match_winner
    scope:domcom_world_tournament_host = {
        add_to_variable_list = { name = domcom_world_tournament_next target = scope:domcom_world_tournament_match_winner }
        change_variable = { name = domcom_world_tournament_next_count add = 1 }
    }

    # When two survivors entered this round, this match is the championship itself.
    if = {
        limit = { scope:domcom_world_tournament_host = { var:domcom_world_tournament_remaining = 2 } }
        set_variable = { name = domcom_world_tournament_placement value = 5 }
        scope:domcom_world_tournament_host = {
            set_variable = { name = domcom_world_tournament_last_champion value = scope:domcom_world_tournament_match_winner }
            set_variable = { name = domcom_world_tournament_last_champion_rating value = scope:domcom_world_tournament_match_winner.var:domcom_world_tournament_alpha_rating }
            set_variable = { name = domcom_world_tournament_completed_this_run value = 1 }
        }
    }
    scope:domcom_world_tournament_loser = {
        if = {
            limit = { scope:domcom_world_tournament_host = { var:domcom_world_tournament_remaining = 2 } }
            set_variable = { name = domcom_world_tournament_placement value = 4 }
        }
    }

    # Player accounting is performed exactly once per actual contest. Byes never count as matches.
    if = {
        limit = { this = scope:domcom_world_tournament_host }
        scope:domcom_world_tournament_host = {
            change_variable = { name = domcom_world_tournament_player_matches add = 1 }
            change_variable = { name = domcom_world_tournament_player_wins add = 1 }
            set_variable = { name = domcom_world_tournament_last_opponent value = scope:domcom_world_tournament_loser }
        }
    }
    scope:domcom_world_tournament_loser = {
        if = {
            limit = { this = scope:domcom_world_tournament_host }
            scope:domcom_world_tournament_host = {
                change_variable = { name = domcom_world_tournament_player_matches add = 1 }
                change_variable = { name = domcom_world_tournament_player_losses add = 1 }
                set_variable = { name = domcom_world_tournament_player_alive value = 0 }
                set_variable = { name = domcom_world_tournament_last_opponent value = scope:domcom_world_tournament_match_winner }
                set_variable = { name = domcom_world_tournament_last_eliminator value = scope:domcom_world_tournament_match_winner }
                set_variable = { name = domcom_world_tournament_last_eliminator_rating value = scope:domcom_world_tournament_match_winner.var:domcom_world_tournament_alpha_rating }
                set_variable = { name = domcom_world_tournament_last_elimination_odds value = var:domcom_world_tournament_player_current_odds }
            }
        }
    }
}


# Survivors earn standing only when the world-finals field has actually narrowed into the requested percentile.
domcom_world_tournament_mark_survivor_tiers_effect = {
    # Surviving to the final one-eighth of the original field is the gauntlet equivalent of winning an
    # eight-person opening bracket. It earns the consolation tier but does not outrank Top 10/5/1 standings.
    if = {
        limit = { var:domcom_world_tournament_remaining <= var:domcom_world_tournament_qualifier_cutoff }
        every_in_list = {
            variable = domcom_world_tournament_current
            if = { limit = { var:domcom_world_tournament_bracket_champion < 1 } set_variable = { name = domcom_world_tournament_bracket_champion value = 1 } }
            if = {
                limit = { this = scope:domcom_world_tournament_host }
                scope:domcom_world_tournament_host = { set_variable = { name = domcom_world_tournament_player_bracket_champion value = 1 } }
            }
        }
    }
    if = {
        limit = { var:domcom_world_tournament_remaining <= var:domcom_world_tournament_top_10_cutoff }
        every_in_list = { variable = domcom_world_tournament_current if = { limit = { var:domcom_world_tournament_placement < 1 } set_variable = { name = domcom_world_tournament_placement value = 1 } } }
    }
    if = {
        limit = { var:domcom_world_tournament_remaining <= var:domcom_world_tournament_top_5_cutoff }
        every_in_list = { variable = domcom_world_tournament_current if = { limit = { var:domcom_world_tournament_placement < 2 } set_variable = { name = domcom_world_tournament_placement value = 2 } } }
    }
    if = {
        limit = { var:domcom_world_tournament_remaining <= var:domcom_world_tournament_top_1_cutoff }
        every_in_list = { variable = domcom_world_tournament_current if = { limit = { var:domcom_world_tournament_placement < 3 } set_variable = { name = domcom_world_tournament_placement value = 3 } } }
    }
}


# Apply one mutually exclusive standing modifier to every rewarded finisher. Winning an opening strength
# bracket now earns a modest standing even if the entrant falls before the global Top 10%.
domcom_world_tournament_apply_placement_reward_effect = {
    # Persist the player's exact immediate reward for the results report.
    if = {
        limit = { this = scope:domcom_world_tournament_host }
        set_variable = { name = domcom_world_tournament_last_reward_prestige value = 0 }
        set_variable = { name = domcom_world_tournament_last_innovations_gained value = 0 }
    }

    remove_character_modifier = domcom_world_tournament_bracket_champion_modifier
    remove_character_modifier = domcom_world_tournament_top_10_modifier
    remove_character_modifier = domcom_world_tournament_top_5_modifier
    remove_character_modifier = domcom_world_tournament_top_1_modifier
    remove_character_modifier = domcom_world_tournament_runner_up_modifier
    remove_character_modifier = domcom_world_tournament_champion_modifier

    if = {
        limit = { var:domcom_world_tournament_placement = 5 }
        add_character_modifier = { modifier = domcom_world_tournament_champion_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 750 }
        add_prestige = var:domcom_world_tournament_reward_prestige
        if = { limit = { has_legitimacy = yes } domcom_world_gauntlet_raise_legitimacy_stage_effect = yes }
        if = {
            limit = { this = scope:domcom_world_tournament_host exists = culture }
            culture = { add_random_innovation = yes add_random_innovation = yes }
            set_variable = { name = domcom_world_tournament_last_innovations_gained value = 2 }
        }
    }
    else_if = {
        limit = { var:domcom_world_tournament_placement = 4 }
        add_character_modifier = { modifier = domcom_world_tournament_runner_up_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 500 }
        add_prestige = var:domcom_world_tournament_reward_prestige
        if = { limit = { has_legitimacy = yes } add_legitimacy = 100 }
        if = {
            limit = { this = scope:domcom_world_tournament_host exists = culture }
            culture = { add_random_innovation = yes }
            set_variable = { name = domcom_world_tournament_last_innovations_gained value = 1 }
        }
    }
    else_if = {
        limit = { var:domcom_world_tournament_placement = 3 }
        add_character_modifier = { modifier = domcom_world_tournament_top_1_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 350 }
        add_prestige = var:domcom_world_tournament_reward_prestige
        if = { limit = { has_legitimacy = yes } add_legitimacy = 50 }
        if = {
            limit = { this = scope:domcom_world_tournament_host exists = culture }
            culture = { add_random_innovation = yes }
            set_variable = { name = domcom_world_tournament_last_innovations_gained value = 1 }
        }
    }
    else_if = {
        limit = { var:domcom_world_tournament_placement = 2 }
        add_character_modifier = { modifier = domcom_world_tournament_top_5_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 200 }
        add_prestige = var:domcom_world_tournament_reward_prestige
    }
    else_if = {
        limit = { var:domcom_world_tournament_placement = 1 }
        add_character_modifier = { modifier = domcom_world_tournament_top_10_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 100 }
        add_prestige = var:domcom_world_tournament_reward_prestige
    }
    else_if = {
        limit = { var:domcom_world_tournament_bracket_champion >= 1 }
        add_character_modifier = { modifier = domcom_world_tournament_bracket_champion_modifier days = 365 }
        set_variable = { name = domcom_world_tournament_reward_prestige value = scope:domcom_world_tournament_host.var:domcom_world_tournament_field_tier }
        change_variable = { name = domcom_world_tournament_reward_prestige multiply = 75 }
        add_prestige = var:domcom_world_tournament_reward_prestige
    }
    if = {
        limit = { this = scope:domcom_world_tournament_host has_variable = domcom_world_tournament_reward_prestige }
        set_variable = { name = domcom_world_tournament_last_reward_prestige value = var:domcom_world_tournament_reward_prestige }
    }
    remove_variable = domcom_world_tournament_reward_prestige
}

# 2.2.1 seeded elimination gauntlet — results now persist and display the player's exact standing reward.
# 2.2.0 seeded elimination gauntlet. Every tournament list/counter belongs to the player/host.
# Each round repeatedly selects strongest unused vs weakest unused until the field is reduced to one champion.
domcom_world_alpha_tournament_run_effect = {
    save_scope_as = domcom_world_tournament_host
    domcom_world_tournament_collect_entrants_effect = yes

    if = {
        limit = {
            var:domcom_world_tournament_entrant_count >= 8
            var:domcom_world_tournament_player_entered >= 1
        }
        send_interface_toast = { type = event_toast_effect_neutral title = DOMCOM_UI_WORLD_TOURNAMENT_RUNNING_TOAST left_icon = root }
        set_variable = { name = domcom_world_tournament_player_alive value = 1 }
        set_variable = { name = domcom_world_tournament_player_matches value = 0 }
        set_variable = { name = domcom_world_tournament_player_wins value = 0 }
        set_variable = { name = domcom_world_tournament_player_losses value = 0 }
        set_variable = { name = domcom_world_tournament_player_bracket_champion value = 0 }
        set_variable = { name = domcom_world_tournament_last_player_rating value = var:domcom_world_tournament_alpha_rating }
        remove_variable = domcom_world_tournament_last_eliminator
        remove_variable = domcom_world_tournament_last_eliminator_rating
        remove_variable = domcom_world_tournament_last_elimination_odds
        remove_variable = domcom_world_tournament_last_champion
        remove_variable = domcom_world_tournament_last_champion_rating
        set_variable = { name = domcom_world_tournament_completed_this_run value = 0 }
        set_variable = { name = domcom_world_tournament_round value = 0 }
        set_variable = { name = domcom_world_tournament_qualifier_cutoff value = domcom_world_tournament_qualifier_cutoff_value }
        set_variable = { name = domcom_world_tournament_top_10_cutoff value = domcom_world_tournament_top_10_cutoff_value }
        set_variable = { name = domcom_world_tournament_top_5_cutoff value = domcom_world_tournament_top_5_cutoff_value }
        set_variable = { name = domcom_world_tournament_top_1_cutoff value = domcom_world_tournament_top_1_cutoff_value }

        # One global elimination gauntlet. There are no protected weak brackets: every round pairs the
        # strongest remaining seed with the weakest, then second-strongest with second-weakest, etc.
        clear_variable_list = domcom_world_tournament_current
        every_in_list = {
            variable = domcom_world_tournament_entrants
            save_temporary_scope_as = domcom_world_tournament_initial_entrant
            scope:domcom_world_tournament_host = { add_to_variable_list = { name = domcom_world_tournament_current target = scope:domcom_world_tournament_initial_entrant } }
        }
        set_variable = { name = domcom_world_tournament_remaining value = var:domcom_world_tournament_entrant_count }
        domcom_world_tournament_mark_survivor_tiers_effect = yes

        while = {
            limit = {
                var:domcom_world_tournament_remaining > 1
                var:domcom_world_tournament_round < 20
            }
            change_variable = { name = domcom_world_tournament_round add = 1 }
            clear_variable_list = domcom_world_tournament_next
            set_variable = { name = domcom_world_tournament_next_count value = 0 }
            set_variable = { name = domcom_world_tournament_round_unpaired value = var:domcom_world_tournament_remaining }

            # Clear any stale round flags before pairing.
            every_in_list = { variable = domcom_world_tournament_current remove_character_flag = domcom_world_tournament_round_used }

            # Each loop consumes the strongest unused contestant and the weakest unused contestant.
            # With an odd field, the median remaining seed receives the single bye for that round.
            while = {
                limit = { var:domcom_world_tournament_round_unpaired > 1 }

                ordered_in_list = {
                    variable = domcom_world_tournament_current
                    limit = { NOT = { has_character_flag = domcom_world_tournament_round_used } }
                    order_by = { value = domcom_world_tournament_seed_value multiply = -1 }
                    max = 1
                    check_range_bounds = no
                    add_character_flag = domcom_world_tournament_round_used
                    save_temporary_scope_as = domcom_world_tournament_attacker
                }
                ordered_in_list = {
                    variable = domcom_world_tournament_current
                    limit = { NOT = { has_character_flag = domcom_world_tournament_round_used } }
                    order_by = domcom_world_tournament_seed_value
                    max = 1
                    check_range_bounds = no
                    add_character_flag = domcom_world_tournament_round_used
                    save_temporary_scope_as = domcom_world_tournament_defender

                    # Freeze the displayed odds before rolling so an elimination report can explain the upset.
                    set_variable = { name = domcom_world_tournament_match_chance value = domcom_world_tournament_match_chance_value }
                    if = {
                        limit = { scope:domcom_world_tournament_attacker = scope:domcom_world_tournament_host }
                        scope:domcom_world_tournament_host = { set_variable = { name = domcom_world_tournament_player_current_odds value = scope:domcom_world_tournament_defender.var:domcom_world_tournament_match_chance } }
                    }
                    else_if = {
                        limit = { this = scope:domcom_world_tournament_host }
                        scope:domcom_world_tournament_host = {
                            set_variable = { name = domcom_world_tournament_player_current_odds value = 100 }
                            change_variable = { name = domcom_world_tournament_player_current_odds subtract = scope:domcom_world_tournament_defender.var:domcom_world_tournament_match_chance }
                        }
                    }

                    add_character_flag = domcom_world_tournament_attacker_failed
                    random = {
                        chance = domcom_world_tournament_match_chance_value
                        remove_character_flag = domcom_world_tournament_attacker_failed
                        save_temporary_scope_as = domcom_world_tournament_loser
                        scope:domcom_world_tournament_attacker = { domcom_world_tournament_advance_winner_effect = yes }
                    }
                    if = {
                        limit = { has_character_flag = domcom_world_tournament_attacker_failed }
                        remove_character_flag = domcom_world_tournament_attacker_failed
                        scope:domcom_world_tournament_attacker = { save_temporary_scope_as = domcom_world_tournament_loser }
                        domcom_world_tournament_advance_winner_effect = yes
                    }
                    remove_variable = domcom_world_tournament_match_chance
                }
                change_variable = { name = domcom_world_tournament_round_unpaired subtract = 2 }
            }

            # The one unpaired contestant in an odd field receives a bye. It advances but records no win/match.
            if = {
                limit = { var:domcom_world_tournament_round_unpaired = 1 }
                ordered_in_list = {
                    variable = domcom_world_tournament_current
                    limit = { NOT = { has_character_flag = domcom_world_tournament_round_used } }
                    order_by = { value = domcom_world_tournament_seed_value multiply = -1 }
                    max = 1
                    check_range_bounds = no
                    add_character_flag = domcom_world_tournament_round_used
                    save_temporary_scope_as = domcom_world_tournament_bye
                    scope:domcom_world_tournament_host = {
                        add_to_variable_list = { name = domcom_world_tournament_next target = scope:domcom_world_tournament_bye }
                        change_variable = { name = domcom_world_tournament_next_count add = 1 }
                    }
                }
                set_variable = { name = domcom_world_tournament_round_unpaired value = 0 }
            }

            every_in_list = { variable = domcom_world_tournament_current remove_character_flag = domcom_world_tournament_round_used }
            clear_variable_list = domcom_world_tournament_current
            every_in_list = {
                variable = domcom_world_tournament_next
                save_temporary_scope_as = domcom_world_tournament_survivor
                scope:domcom_world_tournament_host = { add_to_variable_list = { name = domcom_world_tournament_current target = scope:domcom_world_tournament_survivor } }
            }
            set_variable = { name = domcom_world_tournament_remaining value = var:domcom_world_tournament_next_count }
            domcom_world_tournament_mark_survivor_tiers_effect = yes
        }

        # Fault-tolerant final survivor recovery. Normally the final match already committed the champion.
        if = {
            limit = { var:domcom_world_tournament_completed_this_run < 1 var:domcom_world_tournament_remaining = 1 }
            ordered_in_list = {
                variable = domcom_world_tournament_current
                order_by = { value = domcom_world_tournament_seed_value multiply = -1 }
                max = 1
                check_range_bounds = no
                set_variable = { name = domcom_world_tournament_placement value = 5 }
                save_temporary_scope_as = domcom_world_tournament_recovered_champion
                scope:domcom_world_tournament_host = {
                    set_variable = { name = domcom_world_tournament_last_champion value = scope:domcom_world_tournament_recovered_champion }
                    set_variable = { name = domcom_world_tournament_last_champion_rating value = scope:domcom_world_tournament_recovered_champion.var:domcom_world_tournament_alpha_rating }
                    set_variable = { name = domcom_world_tournament_completed_this_run value = 1 }
                }
            }
        }

        every_in_list = { variable = domcom_world_tournament_entrants domcom_world_tournament_apply_placement_reward_effect = yes }

        set_variable = { name = domcom_world_tournament_last_field_size value = var:domcom_world_tournament_entrant_count }
        set_variable = { name = domcom_world_tournament_last_field_tier value = var:domcom_world_tournament_field_tier }
        set_variable = { name = domcom_world_tournament_last_wins value = var:domcom_world_tournament_player_wins }
        set_variable = { name = domcom_world_tournament_last_matches value = var:domcom_world_tournament_player_matches }
        set_variable = { name = domcom_world_tournament_last_placement value = var:domcom_world_tournament_placement }
        set_variable = { name = domcom_world_tournament_last_bracket_champion value = var:domcom_world_tournament_player_bracket_champion }
        change_variable = { name = domcom_alpha_attempts add = var:domcom_world_tournament_player_matches }
        change_variable = { name = domcom_alpha_successes add = var:domcom_world_tournament_player_wins }
        change_variable = { name = domcom_alpha_failures add = var:domcom_world_tournament_player_losses }

        if = {
            limit = { var:domcom_world_tournament_completed_this_run >= 1 has_variable = domcom_world_tournament_last_champion }
            add_character_flag = { flag = domcom_world_alpha_tournament_recent days = 365 }
            change_variable = { name = domcom_world_gauntlet_runs add = 1 }
            send_interface_toast = { type = event_toast_effect_good title = DOMCOM_UI_WORLD_TOURNAMENT_COMPLETE_TOAST left_icon = root }
            trigger_event = { id = domcom_alpha.300 }
        }
        else = {
            remove_character_flag = domcom_world_alpha_tournament_recent
            send_interface_toast = { type = event_toast_effect_bad title = DOMCOM_UI_WORLD_TOURNAMENT_FAILED_TOAST left_icon = root }
        }
        remove_variable = domcom_world_tournament_completed_this_run
    }
    else_if = {
        limit = { var:domcom_world_tournament_player_entered < 1 }
        send_interface_toast = { type = event_toast_effect_neutral title = DOMCOM_UI_WORLD_TOURNAMENT_NOT_ENTRANT_TOAST left_icon = root }
    }
    else = {
        send_interface_toast = { type = event_toast_effect_neutral title = DOMCOM_UI_WORLD_TOURNAMENT_TOO_SMALL_TOAST left_icon = root }
    }

    if = {
        limit = { has_variable_list = domcom_world_tournament_entrants }
        every_in_list = {
            variable = domcom_world_tournament_entrants
            remove_character_flag = domcom_world_tournament_round_used
            remove_variable = domcom_world_tournament_cuck_count
            remove_variable = domcom_world_tournament_placement
            remove_variable = domcom_world_tournament_bracket_champion
            remove_variable = domcom_world_tournament_alpha_rating
            remove_variable = domcom_world_tournament_match_chance
        }
    }
    clear_variable_list = domcom_world_tournament_entrants
    clear_variable_list = domcom_world_tournament_current
    clear_variable_list = domcom_world_tournament_next
    clear_variable_list = domcom_world_tournament_finalists
    clear_variable_list = domcom_world_tournament_bracket_current
    clear_variable_list = domcom_world_tournament_bracket_next
    remove_variable = domcom_world_tournament_pair_waiting
    remove_variable = domcom_world_tournament_bracket_pair_waiting
    remove_variable = domcom_world_tournament_round_unpaired
    remove_variable = domcom_world_tournament_player_current_odds
    remove_variable = domcom_world_tournament_qualifier_cutoff
}



# ---------------------------------------------------------------------------
# JOLLY RANCHER MODE — optional dynasty-wide removal of Lover's Pox / Great Pox
# ---------------------------------------------------------------------------
domcom_jolly_rancher_cleanse_effect = {
    if = { limit = { has_trait = lovers_pox } remove_trait = lovers_pox }
    if = { limit = { has_trait = great_pox } remove_trait = great_pox }
}

domcom_jolly_rancher_player_dynasty_effect = {
    # The player gets a permanent visible marker while the dynasty toggle is active. This makes the
    # mode's state inspectable at a glance instead of living only in a hidden dynasty variable.
    if = {
        limit = {
            is_alive = yes
            NOT = { has_character_modifier = domcom_jolly_rancher_active_modifier }
        }
        add_character_modifier = { modifier = domcom_jolly_rancher_active_modifier }
    }
    if = { limit = { is_alive = yes } domcom_jolly_rancher_cleanse_effect = yes }
    if = {
        limit = { exists = dynasty }
        dynasty = {
            every_dynasty_member = {
                limit = { is_alive = yes }
                domcom_jolly_rancher_cleanse_effect = yes
            }
        }
    }
}


# ============================================================================
# v2.5.0 — EXPLICIT PLAYER CUCK OPT-OUT
# ============================================================================
# This is intentionally stronger than the provenance repair. The player explicitly asked Dominion to
# forget their personal cuck state, so genuine and erroneous evidence are both removed for this subject.
# Children are then re-evaluated normally: Spawn of a Cuck remains only if another biological/recorded
# parent is still independently Cucked.
domcom_player_strip_cuck_state_effect = {
    save_scope_as = domcom_cuck_optout_subject

    # Remove the subject from every recorded Patron registry before forgetting the links.
    if = {
        limit = { has_variable = domcom_cuck_registry_patron }
        var:domcom_cuck_registry_patron = {
            if = { limit = { has_variable_list = domcom_cucked_registry } remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_cuck_optout_subject } }
            if = { limit = { has_variable_list = domcom_sex_cuck_targets } remove_list_variable = { name = domcom_sex_cuck_targets target = scope:domcom_cuck_optout_subject } }
        }
    }
    if = {
        limit = { has_variable_list = domcom_cuck_patrons }
        every_in_list = {
            variable = domcom_cuck_patrons
            if = { limit = { has_variable_list = domcom_cucked_registry } remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_cuck_optout_subject } }
            if = { limit = { has_variable_list = domcom_sex_cuck_targets } remove_list_variable = { name = domcom_sex_cuck_targets target = scope:domcom_cuck_optout_subject } }
        }
    }
    if = {
        limit = { has_variable = domcom_patron }
        var:domcom_patron = {
            if = { limit = { has_variable_list = domcom_owned_registry } remove_list_variable = { name = domcom_owned_registry target = scope:domcom_cuck_optout_subject } }
        }
    }
    if = {
        limit = { has_variable = domcom_patron_dynasty }
        var:domcom_patron_dynasty = {
            if = { limit = { has_variable_list = domcom_owned_subjects } remove_list_variable = { name = domcom_owned_subjects target = scope:domcom_cuck_optout_subject } }
        }
    }
    if = { limit = { is_target_in_global_variable_list = { name = domcom_all_cucked target = scope:domcom_cuck_optout_subject } } remove_list_global_variable = { name = domcom_all_cucked target = scope:domcom_cuck_optout_subject } }

    # Remove Dominion's currently displayed nickname now, but restore only after Cuck XP/state has been
    # cleared below. The old 2.4.2 order tried the legacy Blood-Father fallback while Cuck XP was still
    # positive, which is why the repair button could remove "the Cucked" without giving Blood-Father back.
    if = {
        limit = { has_nickname = nick_domcom_the_cucked }
        add_character_flag = domcom_cuck_nickname_removed_by_repair
        remove_nickname = yes
    }

    remove_character_flag = domcom_cucked
    remove_character_flag = domcom_cuck_registry_added
    remove_character_flag = domcom_global_cuck_registry_added
    remove_character_flag = domcom_owned_cuck
    remove_character_flag = domcom_collapse_ready
    remove_character_flag = domcom_reclaimed_cuck_recent
    remove_character_modifier = domcom_cucked_modifier
    remove_character_modifier = domcom_owned_modifier
    remove_character_modifier = domcom_humiliated_stage_modifier
    remove_character_modifier = domcom_submissive_stage_modifier
    remove_character_modifier = domcom_broken_stage_modifier
    remove_character_modifier = domcom_abject_stage_modifier
    remove_character_modifier = domcom_final_submission_modifier
    # These temporary duel penalties are also consequences of the cuckoldry system. A player choosing
    # the explicit opt-out should not remain mechanically punished by a state Dominion has just erased.
    remove_character_modifier = domcom_cuck_duel_defeat_modifier
    remove_character_modifier = domcom_cuck_duel_refusal_modifier
    if = { limit = { has_trait = domcom_cucked_trait } remove_trait = domcom_cucked_trait }

    set_variable = { name = domcom_cuck_xp value = 0 }
    remove_variable = domcom_cuck_origin_patron
    remove_variable = domcom_cuck_patron
    remove_variable = domcom_cuck_registry_patron
    remove_variable = domcom_patron
    remove_variable = domcom_patron_dynasty
    remove_variable = domcom_compromised_partner
    clear_variable_list = domcom_cuck_patrons
    clear_variable_list = domcom_sex_evidence_patrons
    clear_variable_list = domcom_betrayal_evidence_patrons

    # Restore after XP is zeroed. This also repairs saves where Alpha Gauntlet already stripped the Cucked
    # nickname but left our 2.4.2 displaced-nickname marker behind. Arbitrary unknown third-party nickname
    # keys still cannot be serialized/reapplied by CK3, but every explicitly recorded Dominion nickname and
    # the vanilla Blood-Father/Blood-Mother fallback can recover here.
    if = {
        limit = {
            OR = {
                has_character_flag = domcom_cuck_nickname_removed_by_repair
                has_character_flag = domcom_restore_nick_blood_motherfather
                has_character_flag = domcom_restore_nick_the_remade
                has_character_flag = domcom_restore_nick_the_unmanned
                has_character_flag = domcom_restore_nick_the_softened
                has_character_flag = domcom_restore_nick_dynasty_slave
                has_character_flag = domcom_restore_nick_personal_slave
                AND = { NOT = { has_any_nickname = yes } exists = dynasty dynasty = { has_dynasty_modifier = strong_blood } }
            }
        }
        add_character_flag = domcom_cuck_nickname_removed_by_repair
        domcom_restore_displaced_nickname_after_bad_cuck_effect = yes
    }

    # Remove cuck-specific family opinions from every partner stored by the cuck record, including former
    # partners who are no longer current consorts, then also sweep current consorts as a legacy fallback.
    if = {
        limit = { has_variable_list = domcom_compromised_partners }
        every_in_list = {
            variable = domcom_compromised_partners
            save_temporary_scope_as = domcom_optout_recorded_partner
            scope:domcom_cuck_optout_subject = { remove_opinion = { target = scope:domcom_optout_recorded_partner modifier = domcom_cucked_partner_opinion } }
            every_child = {
                save_temporary_scope_as = domcom_optout_recorded_partner_child
                scope:domcom_cuck_optout_subject = { remove_opinion = { target = scope:domcom_optout_recorded_partner_child modifier = domcom_cucked_child_opinion } }
            }
        }
    }

    # Remove cuck-specific family opinions created by this subject, then rebuild children's stigma from
    # the remaining parents. This preserves Spawn of a Cuck when the other parent is still genuinely Cucked.
    every_consort = {
        save_temporary_scope_as = domcom_optout_partner
        scope:domcom_cuck_optout_subject = { remove_opinion = { target = scope:domcom_optout_partner modifier = domcom_cucked_partner_opinion } }
    }
    every_child = {
        save_temporary_scope_as = domcom_optout_child
        scope:domcom_cuck_optout_subject = { remove_opinion = { target = scope:domcom_optout_child modifier = domcom_cucked_child_opinion } }
        domcom_refresh_spawn_of_cuck_effect = yes
    }
    clear_variable_list = domcom_compromised_partners

    domcom_prepare_ui_effect = yes
}


# v2.5.0: expose Lick the Tip income in CK3's native resource breakdowns instead of silently paying
# currencies from script. Binary component modifiers reproduce the exact rounded monthly values with
# at most a handful of visible sources and are cheap to refresh.
domcom_refresh_cult_resource_modifiers_effect = {
    remove_character_modifier = domcom_cult_gold_1
    remove_character_modifier = domcom_cult_gold_2
    remove_character_modifier = domcom_cult_gold_4
    remove_character_modifier = domcom_cult_gold_8
    remove_character_modifier = domcom_cult_gold_16
    remove_character_modifier = domcom_cult_prestige_1
    remove_character_modifier = domcom_cult_prestige_2
    remove_character_modifier = domcom_cult_prestige_4
    remove_character_modifier = domcom_cult_prestige_8
    remove_character_modifier = domcom_cult_prestige_16
    remove_character_modifier = domcom_cult_prestige_32
    remove_character_modifier = domcom_cult_prestige_64
    remove_character_modifier = domcom_cult_piety_1
    remove_character_modifier = domcom_cult_piety_2
    remove_character_modifier = domcom_cult_piety_4
    remove_character_modifier = domcom_cult_piety_8
    remove_character_modifier = domcom_cult_piety_16
    remove_character_modifier = domcom_cult_piety_32
    remove_character_modifier = domcom_cult_piety_64
    remove_character_modifier = domcom_cult_renown_1
    remove_character_modifier = domcom_cult_renown_2
    remove_character_modifier = domcom_cult_renown_4
    remove_character_modifier = domcom_cult_renown_8
    set_variable = { name = domcom_cult_gold_remaining value = var:domcom_cult_monthly_gold }
    if = { limit = { var:domcom_cult_gold_remaining >= 16 } add_character_modifier = { modifier = domcom_cult_gold_16 } change_variable = { name = domcom_cult_gold_remaining subtract = 16 } }
    if = { limit = { var:domcom_cult_gold_remaining >= 8 } add_character_modifier = { modifier = domcom_cult_gold_8 } change_variable = { name = domcom_cult_gold_remaining subtract = 8 } }
    if = { limit = { var:domcom_cult_gold_remaining >= 4 } add_character_modifier = { modifier = domcom_cult_gold_4 } change_variable = { name = domcom_cult_gold_remaining subtract = 4 } }
    if = { limit = { var:domcom_cult_gold_remaining >= 2 } add_character_modifier = { modifier = domcom_cult_gold_2 } change_variable = { name = domcom_cult_gold_remaining subtract = 2 } }
    if = { limit = { var:domcom_cult_gold_remaining >= 1 } add_character_modifier = { modifier = domcom_cult_gold_1 } change_variable = { name = domcom_cult_gold_remaining subtract = 1 } }
    remove_variable = domcom_cult_gold_remaining
    set_variable = { name = domcom_cult_prestige_remaining value = var:domcom_cult_monthly_prestige }
    if = { limit = { var:domcom_cult_prestige_remaining >= 64 } add_character_modifier = { modifier = domcom_cult_prestige_64 } change_variable = { name = domcom_cult_prestige_remaining subtract = 64 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 32 } add_character_modifier = { modifier = domcom_cult_prestige_32 } change_variable = { name = domcom_cult_prestige_remaining subtract = 32 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 16 } add_character_modifier = { modifier = domcom_cult_prestige_16 } change_variable = { name = domcom_cult_prestige_remaining subtract = 16 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 8 } add_character_modifier = { modifier = domcom_cult_prestige_8 } change_variable = { name = domcom_cult_prestige_remaining subtract = 8 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 4 } add_character_modifier = { modifier = domcom_cult_prestige_4 } change_variable = { name = domcom_cult_prestige_remaining subtract = 4 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 2 } add_character_modifier = { modifier = domcom_cult_prestige_2 } change_variable = { name = domcom_cult_prestige_remaining subtract = 2 } }
    if = { limit = { var:domcom_cult_prestige_remaining >= 1 } add_character_modifier = { modifier = domcom_cult_prestige_1 } change_variable = { name = domcom_cult_prestige_remaining subtract = 1 } }
    remove_variable = domcom_cult_prestige_remaining
    set_variable = { name = domcom_cult_piety_remaining value = var:domcom_cult_monthly_piety }
    if = { limit = { var:domcom_cult_piety_remaining >= 64 } add_character_modifier = { modifier = domcom_cult_piety_64 } change_variable = { name = domcom_cult_piety_remaining subtract = 64 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 32 } add_character_modifier = { modifier = domcom_cult_piety_32 } change_variable = { name = domcom_cult_piety_remaining subtract = 32 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 16 } add_character_modifier = { modifier = domcom_cult_piety_16 } change_variable = { name = domcom_cult_piety_remaining subtract = 16 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 8 } add_character_modifier = { modifier = domcom_cult_piety_8 } change_variable = { name = domcom_cult_piety_remaining subtract = 8 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 4 } add_character_modifier = { modifier = domcom_cult_piety_4 } change_variable = { name = domcom_cult_piety_remaining subtract = 4 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 2 } add_character_modifier = { modifier = domcom_cult_piety_2 } change_variable = { name = domcom_cult_piety_remaining subtract = 2 } }
    if = { limit = { var:domcom_cult_piety_remaining >= 1 } add_character_modifier = { modifier = domcom_cult_piety_1 } change_variable = { name = domcom_cult_piety_remaining subtract = 1 } }
    remove_variable = domcom_cult_piety_remaining
    set_variable = { name = domcom_cult_renown_remaining value = var:domcom_cult_monthly_renown }
    if = { limit = { var:domcom_cult_renown_remaining >= 8 } add_character_modifier = { modifier = domcom_cult_renown_8 } change_variable = { name = domcom_cult_renown_remaining subtract = 8 } }
    if = { limit = { var:domcom_cult_renown_remaining >= 4 } add_character_modifier = { modifier = domcom_cult_renown_4 } change_variable = { name = domcom_cult_renown_remaining subtract = 4 } }
    if = { limit = { var:domcom_cult_renown_remaining >= 2 } add_character_modifier = { modifier = domcom_cult_renown_2 } change_variable = { name = domcom_cult_renown_remaining subtract = 2 } }
    if = { limit = { var:domcom_cult_renown_remaining >= 1 } add_character_modifier = { modifier = domcom_cult_renown_1 } change_variable = { name = domcom_cult_renown_remaining subtract = 1 } }
    remove_variable = domcom_cult_renown_remaining
}

# v2.5.6: physical Endowment tiers are display traits, not CK3 genetic traits. Clean old recessive copies
# from minors/women who cannot express an Endowment, then initialize/synchronize every valid adult body.
domcom_migrate_endowment_expression_v256_once_effect = {
    if = {
        limit = { NOT = { has_global_variable = domcom_endowment_expression_v256_migrated } }
        every_living_character = {
            if = {
                limit = {
                    OR = {
                        age < 18
                        NOT = { domcom_should_express_endowment_trigger = yes }
                    }
                }
                domcom_clear_endowment_traits_effect = yes
            }
            else_if = {
                limit = {
                    age >= 18
                    domcom_should_express_endowment_trigger = yes
                }
                domcom_assign_endowment_effect = yes
                domcom_initialize_endowment_mastery_effect = yes
                domcom_refresh_endowment_expression_effect = yes
            }
        }
        set_global_variable = domcom_endowment_expression_v256_migrated
    }
}


# ============================================================================
# 2.5.12 SELECTIVE BODY REROLL
# ============================================================================

domcom_clear_body_reroll_selection_effect = {
    if = {
        limit = { has_variable_list = domcom_ui_body_reroll_raw }
        every_in_list = { variable = domcom_ui_body_reroll_raw remove_character_flag = domcom_ui_body_reroll_selected }
    }
    clear_variable_list = domcom_ui_body_reroll_raw
    clear_variable_list = domcom_ui_body_reroll_page_list
    set_variable = { name = domcom_ui_body_reroll_selected_count value = 0 }
}

domcom_recount_body_reroll_selected_effect = {
    save_scope_as = domcom_body_reroll_viewer
    set_variable = { name = domcom_ui_body_reroll_selected_count value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_body_reroll_raw }
        every_in_list = {
            variable = domcom_ui_body_reroll_raw
            limit = { has_character_flag = domcom_ui_body_reroll_selected }
            scope:domcom_body_reroll_viewer = { change_variable = { name = domcom_ui_body_reroll_selected_count add = 1 } }
        }
    }
}

domcom_build_body_reroll_page_effect = {
    domcom_standard_page_size_effect = yes
    if = { limit = { NOT = { has_variable = domcom_ui_body_reroll_page } } set_variable = { name = domcom_ui_body_reroll_page value = 0 } }
    clear_variable_list = domcom_ui_body_reroll_page_list
    set_variable = { name = domcom_ui_body_reroll_total value = 0 }
    set_variable = { name = domcom_ui_body_reroll_last_page value = 0 }
    set_variable = { name = domcom_ui_body_reroll_page_fill value = 0 }
    if = {
        limit = { has_variable_list = domcom_ui_body_reroll_raw }
        every_in_list = {
            variable = domcom_ui_body_reroll_raw
            prev = {
                if = { limit = { var:domcom_ui_body_reroll_page_fill >= var:domcom_ui_standard_page_size } change_variable = { name = domcom_ui_body_reroll_last_page add = 1 } set_variable = { name = domcom_ui_body_reroll_page_fill value = 0 } }
                change_variable = { name = domcom_ui_body_reroll_page_fill add = 1 }
                change_variable = { name = domcom_ui_body_reroll_total add = 1 }
            }
        }
    }
    if = { limit = { var:domcom_ui_body_reroll_page < 0 } set_variable = { name = domcom_ui_body_reroll_page value = 0 } }
    if = { limit = { var:domcom_ui_body_reroll_page > var:domcom_ui_body_reroll_last_page } set_variable = { name = domcom_ui_body_reroll_page value = var:domcom_ui_body_reroll_last_page } }
    set_variable = { name = domcom_ui_body_reroll_first value = var:domcom_ui_body_reroll_page }
    change_variable = { name = domcom_ui_body_reroll_first multiply = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_body_reroll_stop value = var:domcom_ui_body_reroll_first }
    change_variable = { name = domcom_ui_body_reroll_stop add = var:domcom_ui_standard_page_size }
    set_variable = { name = domcom_ui_body_reroll_index value = 0 }
    save_scope_as = domcom_body_reroll_viewer
    if = {
        limit = { has_variable_list = domcom_ui_body_reroll_raw }
        every_in_list = {
            variable = domcom_ui_body_reroll_raw
            save_temporary_scope_as = domcom_body_reroll_candidate
            scope:domcom_body_reroll_viewer = {
                if = { limit = { var:domcom_ui_body_reroll_index >= var:domcom_ui_body_reroll_first var:domcom_ui_body_reroll_index < var:domcom_ui_body_reroll_stop } add_to_variable_list = { name = domcom_ui_body_reroll_page_list target = scope:domcom_body_reroll_candidate } }
                change_variable = { name = domcom_ui_body_reroll_index add = 1 }
            }
        }
    }
    set_variable = { name = domcom_ui_body_reroll_display_first value = var:domcom_ui_body_reroll_first }
    change_variable = { name = domcom_ui_body_reroll_display_first add = 1 }
    set_variable = { name = domcom_ui_body_reroll_display_stop value = var:domcom_ui_body_reroll_stop }
    if = { limit = { var:domcom_ui_body_reroll_display_stop > var:domcom_ui_body_reroll_total } set_variable = { name = domcom_ui_body_reroll_display_stop value = var:domcom_ui_body_reroll_total } }
    if = { limit = { var:domcom_ui_body_reroll_total <= 0 } set_variable = { name = domcom_ui_body_reroll_display_first value = 0 } set_variable = { name = domcom_ui_body_reroll_display_stop value = 0 } }
    set_variable = { name = domcom_ui_body_reroll_page_display value = var:domcom_ui_body_reroll_page }
    change_variable = { name = domcom_ui_body_reroll_page_display add = 1 }
    set_variable = { name = domcom_ui_body_reroll_pages_display value = var:domcom_ui_body_reroll_last_page }
    change_variable = { name = domcom_ui_body_reroll_pages_display add = 1 }
}

domcom_prepare_body_reroll_roster_effect = {
    domcom_clear_body_reroll_selection_effect = yes
    save_scope_as = domcom_body_reroll_viewer
    if = {
        limit = { is_alive = yes age >= 18 OR = { is_female = yes domcom_should_express_endowment_trigger = yes } }
        add_to_variable_list = { name = domcom_ui_body_reroll_raw target = this }
    }
    every_courtier_or_guest = {
        limit = { is_alive = yes age >= 18 OR = { is_female = yes domcom_should_express_endowment_trigger = yes } }
        save_temporary_scope_as = domcom_body_reroll_candidate
        scope:domcom_body_reroll_viewer = { add_to_variable_list = { name = domcom_ui_body_reroll_raw target = scope:domcom_body_reroll_candidate } }
    }
    set_variable = { name = domcom_ui_body_reroll_page value = 0 }
    domcom_build_body_reroll_page_effect = yes
    domcom_recount_body_reroll_selected_effect = yes
}

# Rerolls only the character's applicable physical body profile(s). Mastery and attraction preferences
# remain intact. A Carnalitas-recognized futanari woman legitimately rerolls both body profiles.
domcom_reroll_character_body_profile_effect = {
    if = {
        limit = { age >= 18 domcom_should_express_endowment_trigger = yes }
        remove_variable = domcom_length_tenths
        remove_variable = domcom_girth_tenths
        remove_variable = domcom_locked_length_tenths
        remove_variable = domcom_locked_girth_tenths
        remove_variable = domcom_canonical_length_tenths
        remove_variable = domcom_canonical_girth_tenths
        remove_variable = domcom_locked_endowment_category
        remove_variable = domcom_endowment_category
        remove_variable = domcom_endowment_index
        remove_variable = domcom_sire_length_tenths
        remove_variable = domcom_sire_girth_tenths
        remove_variable = domcom_designer_endowment_choice
        remove_character_flag = domcom_endowment_locked
        remove_character_flag = domcom_native_endowment_mastery_seeded
        remove_character_flag = domcom_mastery_track_normalized_v250
        domcom_clear_endowment_traits_effect = yes
        domcom_rebuild_clear_external_traits_effect = yes
        domcom_assign_endowment_effect = yes
        domcom_initialize_endowment_mastery_effect = yes
    }
    if = {
        limit = { age >= 18 is_female = yes }
        remove_variable = domcom_underbust_tenths
        remove_variable = domcom_bust_tenths
        remove_variable = domcom_breast_fullness_tenths
        remove_variable = domcom_locked_underbust_tenths
        remove_variable = domcom_locked_bust_tenths
        remove_variable = domcom_locked_breast_fullness_tenths
        remove_variable = domcom_breast_category
        remove_variable = domcom_designer_breast_choice
        remove_character_flag = domcom_use_maternal_breast_roll
        remove_character_flag = domcom_native_breast_mastery_seeded
        domcom_clear_breast_traits_effect = yes
        domcom_assign_breast_profile_effect = yes
        domcom_initialize_breast_mastery_effect = yes
    }
}

domcom_apply_selected_body_rerolls_effect = {
    save_scope_as = domcom_body_reroll_viewer
    if = {
        limit = { has_variable_list = domcom_ui_body_reroll_raw }
        every_in_list = {
            variable = domcom_ui_body_reroll_raw
            limit = { has_character_flag = domcom_ui_body_reroll_selected is_alive = yes age >= 18 }
            remove_character_flag = domcom_ui_body_reroll_selected
            domcom_reroll_character_body_profile_effect = yes
        }
    }
    scope:domcom_body_reroll_viewer = {
        domcom_prepare_body_reroll_roster_effect = yes
        send_interface_toast = { type = event_toast_effect_good title = DOMCOM_UI_BODY_REROLL_DONE_TOAST left_icon = root }
    }
}


# ==========================================================================
# v2.5.1 — REVEAL TRUE PARENTAGE
# Run from the child. scope:domcom_parentage_revealer is the actor.
# This never invents parentage: it only publicizes CK3's already-stored real_father.
# ==========================================================================
domcom_reveal_true_parentage_effect = {
    if = {
        limit = {
            exists = real_father
            exists = father
            NOT = { father = real_father }
        }
        real_father = { save_scope_as = domcom_true_father }
        father = { save_scope_as = domcom_assumed_father }
        # Preserve displaced-blood succession context before the public father is rewritten.
        # This effect keys its checks to the biological Patron, not to whichever involved parent exposed the truth.
        scope:domcom_true_father = { save_scope_as = domcom_ack_patron }
        domcom_record_displaced_blood_heir_effect = yes
        set_father = scope:domcom_true_father
        if = { limit = { scope:domcom_true_father = { exists = house } } set_house = scope:domcom_true_father.house }

        # Once exposed, this child is no longer hidden blood. Remove it from the biological father's
        # hidden-blood registry without falsely incrementing the voluntary "acknowledged" counter.
        remove_character_flag = domcom_hidden_blood_child
        add_character_flag = domcom_blood_acknowledged_child
        save_temporary_scope_as = domcom_revealed_child
        scope:domcom_true_father = {
            if = {
                limit = { has_variable_list = domcom_blood_registry }
                remove_list_variable = { name = domcom_blood_registry target = scope:domcom_revealed_child }
            }
        }
        domcom_refresh_spawn_of_cuck_effect = yes
    }
}


# v2.6.67 — player utility for a character whose save already contains a biological father/House
# but whose public identity is still lowborn, assigned to the wrong House, or still attached to an
# assumed father. Marriage/betrothal is intentionally irrelevant and is never altered here.
domcom_restore_concealed_identity_effect = {
    if = {
        limit = {
            exists = real_father
            real_father = { exists = house }
        }
        real_father = { save_scope_as = domcom_identity_true_father }

        if = {
            limit = {
                exists = father
                NOT = { father = real_father }
            }
            domcom_reveal_true_parentage_effect = yes
        }
        else = {
            if = {
                limit = { NOT = { exists = father } }
                set_father = scope:domcom_identity_true_father
            }
            if = {
                limit = {
                    OR = {
                        NOT = { exists = house }
                        NOT = { house = scope:domcom_identity_true_father.house }
                    }
                }
                set_house = scope:domcom_identity_true_father.house
            }

            remove_character_flag = domcom_hidden_blood_child
            add_character_flag = domcom_blood_acknowledged_child
            save_temporary_scope_as = domcom_restored_identity_child
            scope:domcom_identity_true_father = {
                if = {
                    limit = { has_variable_list = domcom_blood_registry }
                    remove_list_variable = { name = domcom_blood_registry target = scope:domcom_restored_identity_child }
                }
            }
            domcom_refresh_spawn_of_cuck_effect = yes
        }
    }
}


# v2.5.1 — influence-only lover-bait success. Attraction remains directed at the intermediary.
# Run from target with scope:domcom_bait_patron and scope:domcom_bait saved.
domcom_apply_entice_through_lover_success_effect = {
    domcom_initialize_attraction_profile_effect = yes
    if = { limit = { NOT = { has_variable = domcom_obedience } } set_variable = { name = domcom_obedience value = 0 } }
    if = {
        limit = { OR = { NOT = { has_variable = domcom_obedience_patron } var:domcom_obedience_patron = scope:domcom_bait_patron } }
        set_variable = { name = domcom_obedience_patron value = scope:domcom_bait_patron }
        change_variable = { name = domcom_obedience add = 80 }
        if = { limit = { var:domcom_obedience > 1000 } set_variable = { name = domcom_obedience value = 1000 } }
        domcom_refresh_obedience_stage_effect = yes
        if = {
            limit = { NOT = { has_character_flag = domcom_tantalized_registered } }
            add_character_flag = domcom_tantalized_registered
            save_temporary_scope_as = domcom_bait_subject
            scope:domcom_bait_patron = { add_to_variable_list = { name = domcom_tantalized_registry target = scope:domcom_bait_subject } }
        }
    }
}


# 2.6.57 — state-aware lover journal hygiene.
# Keep one original "became lovers" memory per partner instead of deleting the entire lover category.
# Breakup memories are suppressed while the pair is still Lovers/Soulmates OR while either direction
# still has live Dominion state. Once that state truly ends (for example Cuck XP reaches zero), one real
# breakup memory is allowed to remain. The registries are player-local and bounded by actual journal partners.
domcom_cleanup_routine_lover_memories_effect = {
    save_scope_as = domcom_journal_owner

    # Preserve one love-origin memory per pair; delete later re-add churn.
    every_memory = {
        limit = {
            has_memory_type = became_lovers
            exists = memory_participant:new_relation
        }
        memory_participant:new_relation = { save_temporary_scope_as = domcom_journal_partner }
        if = {
            limit = { has_variable = domcom_journal_first_love_anchor }
            # This is the retained journal anchor for the pair.
        }
        else_if = {
            limit = {
                scope:domcom_journal_owner = {
                    has_variable_list = domcom_journal_first_love_partners
                    any_in_list = {
                        variable = domcom_journal_first_love_partners
                        this = scope:domcom_journal_partner
                    }
                }
            }
            destroy_character_memory = this
        }
        else = {
            set_variable = { name = domcom_journal_first_love_anchor value = 1 }
            scope:domcom_journal_owner = {
                add_to_variable_list = {
                    name = domcom_journal_first_love_partners
                    target = scope:domcom_journal_partner
                }
            }
        }
    }

    # A vanilla breakup is journal noise if the pair is still together in CK3 OR the Dominion layer
    # still says the bond is active. A true post-Dominion breakup gets one retained journal entry.
    every_memory = {
        limit = {
            has_memory_type = broke_up_lovers
            exists = memory_participant:old_lover
        }
        memory_participant:old_lover = { save_temporary_scope_as = domcom_journal_partner }
        if = {
            limit = {
                OR = {
                    scope:domcom_journal_owner = { has_relation_lover = scope:domcom_journal_partner }
                    scope:domcom_journal_owner = { has_relation_soulmate = scope:domcom_journal_partner }
                    scope:domcom_journal_owner = {
                        domcom_has_active_dominion_to_patron_trigger = { PATRON = scope:domcom_journal_partner }
                    }
                    scope:domcom_journal_partner = {
                        domcom_has_active_dominion_to_patron_trigger = { PATRON = scope:domcom_journal_owner }
                    }
                }
            }
            destroy_character_memory = this
        }
        else_if = {
            limit = { has_variable = domcom_journal_true_breakup_anchor }
            # Retain the first genuine end-state memory for this pair.
        }
        else_if = {
            limit = {
                scope:domcom_journal_owner = {
                    has_variable_list = domcom_journal_true_breakup_partners
                    any_in_list = {
                        variable = domcom_journal_true_breakup_partners
                        this = scope:domcom_journal_partner
                    }
                }
            }
            destroy_character_memory = this
        }
        else = {
            set_variable = { name = domcom_journal_true_breakup_anchor value = 1 }
            scope:domcom_journal_owner = {
                add_to_variable_list = {
                    name = domcom_journal_true_breakup_partners
                    target = scope:domcom_journal_partner
                }
            }
        }
    }
}

