﻿# DDM 2.6 — persistent hunter records, writ hostages, coercion and retrieval restoration.

# Hunter scope. A successful live capture is worth more XP when the quarry is politically valuable.
ddm_record_hunter_live_capture_effect = {
    ddm_update_hunter_level_effect = yes
    change_variable = { name = ddm_hunter_attempts add = 1 }
    change_variable = { name = ddm_hunter_wins add = 1 }
    change_variable = { name = ddm_hunter_live_captures add = 1 }
    change_variable = { name = ddm_hunter_xp add = 25 }
    if = { limit = { scope:ddm_hunter_capture_target = { is_landed = yes } } change_variable = { name = ddm_hunter_xp add = 10 } }
    if = { limit = { scope:ddm_hunter_capture_target = { highest_held_title_tier >= tier_duchy } } change_variable = { name = ddm_hunter_xp add = 10 } }
    if = { limit = { scope:ddm_hunter_capture_target = { highest_held_title_tier >= tier_kingdom } } change_variable = { name = ddm_hunter_xp add = 15 } }
    if = { limit = { scope:ddm_hunter_capture_target = { highest_held_title_tier >= tier_empire } } change_variable = { name = ddm_hunter_xp add = 25 } }
    # Extra value for a close-family/heir capture of the quarry's recorded origin ruler.
    if = {
        limit = { scope:ddm_hunter_capture_target = { has_variable = ddm_writ_origin_top_liege } }
        scope:ddm_hunter_capture_target.var:ddm_writ_origin_top_liege = { save_scope_as = ddm_hunter_capture_origin }
        if = {
            limit = {
                exists = scope:ddm_hunter_capture_origin
                scope:ddm_hunter_capture_target = {
                    OR = {
                        is_heir_of = scope:ddm_hunter_capture_origin
                        is_close_family_of = scope:ddm_hunter_capture_origin
                    }
                }
            }
            change_variable = { name = ddm_hunter_xp add = 15 }
        }
    }
    ddm_update_hunter_level_effect = yes
}

ddm_record_hunter_loss_effect = {
    ddm_update_hunter_level_effect = yes
    change_variable = { name = ddm_hunter_attempts add = 1 }
    change_variable = { name = ddm_hunter_losses add = 1 }
    change_variable = { name = ddm_hunter_xp add = 5 }
    ddm_update_hunter_level_effect = yes
}

ddm_record_hunter_kill_effect = {
    ddm_update_hunter_level_effect = yes
    change_variable = { name = ddm_hunter_attempts add = 1 }
    change_variable = { name = ddm_hunter_wins add = 1 }
    change_variable = { name = ddm_hunter_kills add = 1 }
    change_variable = { name = ddm_hunter_xp add = 20 }
    ddm_update_hunter_level_effect = yes
}

# Target scope. Call immediately before/after DDM imprisons a character under a writ.
# scope:ddm_writ_captor must be the ruler receiving the captive.
ddm_prepare_writ_hostage_effect = {
    save_scope_as = ddm_writ_hostage_target
    add_character_flag = ddm_writ_hostage
    set_variable = { name = ddm_writ_captor value = scope:ddm_writ_captor }
    remove_variable = ddm_writ_original_employer
    remove_variable = ddm_writ_original_liege
    remove_variable = ddm_writ_origin_top_liege
    remove_variable = ddm_writ_ransom_sponsor

    if = {
        limit = { exists = employer }
        employer = { save_scope_as = ddm_writ_original_employer_scope }
        set_variable = { name = ddm_writ_original_employer value = scope:ddm_writ_original_employer_scope }
    }
    if = {
        limit = { is_landed = yes is_independent_ruler = no exists = liege }
        liege = { save_scope_as = ddm_writ_original_liege_scope }
        set_variable = { name = ddm_writ_original_liege value = scope:ddm_writ_original_liege_scope }
    }
    if = {
        limit = { is_landed = yes }
        top_liege = { save_scope_as = ddm_writ_origin_top_liege_scope }
    }
    else_if = {
        limit = { exists = employer }
        employer = { top_liege = { save_scope_as = ddm_writ_origin_top_liege_scope } }
    }
    if = {
        limit = { exists = scope:ddm_writ_origin_top_liege_scope }
        set_variable = { name = ddm_writ_origin_top_liege value = scope:ddm_writ_origin_top_liege_scope }
        # Reuse the established Retrieval War captive marker so old/new retrieval logic cooperates.
        set_variable = { name = ddm_kidnap_origin_top_liege value = scope:ddm_writ_origin_top_liege_scope }
    }

    # Tiered ransom. The demand is deliberately not capped by the sponsor's cash on hand.
    set_variable = { name = ddm_writ_ransom_amount value = 100 }
    if = { limit = { highest_held_title_tier >= tier_county } set_variable = { name = ddm_writ_ransom_amount value = 250 } }
    if = { limit = { highest_held_title_tier >= tier_duchy } set_variable = { name = ddm_writ_ransom_amount value = 500 } }
    if = { limit = { highest_held_title_tier >= tier_kingdom } set_variable = { name = ddm_writ_ransom_amount value = 1000 } }
    if = { limit = { highest_held_title_tier >= tier_empire } set_variable = { name = ddm_writ_ransom_amount value = 2000 } }
    if = {
        limit = {
            exists = scope:ddm_writ_origin_top_liege_scope
            OR = {
                is_close_family_of = scope:ddm_writ_origin_top_liege_scope
                is_heir_of = scope:ddm_writ_origin_top_liege_scope
            }
        }
        change_variable = { name = ddm_writ_ransom_amount add = 500 }
    }

    # Sponsor priority: spouse, father, mother, then the offended/origin ruler.
    if = {
        limit = { exists = primary_spouse primary_spouse = { is_alive = yes this != scope:ddm_writ_captor } }
        primary_spouse = { save_scope_as = ddm_writ_ransom_sponsor_scope }
    }
    else_if = {
        limit = { exists = father father = { is_alive = yes this != scope:ddm_writ_captor } }
        father = { save_scope_as = ddm_writ_ransom_sponsor_scope }
    }
    else_if = {
        limit = { exists = mother mother = { is_alive = yes this != scope:ddm_writ_captor } }
        mother = { save_scope_as = ddm_writ_ransom_sponsor_scope }
    }
    else_if = {
        limit = { exists = scope:ddm_writ_origin_top_liege_scope scope:ddm_writ_origin_top_liege_scope = { is_alive = yes this != scope:ddm_writ_captor } }
        scope:ddm_writ_origin_top_liege_scope = { save_scope_as = ddm_writ_ransom_sponsor_scope }
    }
    if = { limit = { exists = scope:ddm_writ_ransom_sponsor_scope } set_variable = { name = ddm_writ_ransom_sponsor value = scope:ddm_writ_ransom_sponsor_scope } }

    trigger_event = { id = ddm_manager.5310 days = 30 }
}

# Target scope. Remove the prisoner-only state without deleting origin/coercion data needed by Retrieval War.
ddm_clear_writ_hostage_state_effect = {
    remove_character_flag = ddm_writ_hostage
    remove_character_flag = ddm_writ_retrieval_attempted_state
    remove_variable = ddm_writ_captor
    remove_variable = ddm_writ_ransom_amount
    remove_variable = ddm_writ_ransom_sponsor
    remove_variable = ddm_writ_retrieval_pressure
}

# Target scope. Complete cleanup after voluntary ransom or successful restoration.
ddm_clear_writ_origin_effect = {
    ddm_clear_writ_hostage_state_effect = yes
    remove_variable = ddm_writ_original_employer
    remove_variable = ddm_writ_original_liege
    remove_variable = ddm_writ_origin_top_liege
    remove_variable = ddm_kidnap_origin_top_liege
    remove_variable = ddm_writ_coerced_by
    remove_variable = ddm_writ_coercion_type
    remove_variable = ddm_writ_abdication_successor
    clear_variable_list = ddm_writ_abdicated_titles
}

# Target scope. A delayed hostage check can escalate into the existing Retrieval War.
ddm_try_writ_hostage_retrieval_war_effect = {
    # One political decision per hostage/coercion state. Earlier builds rescheduled this event every
    # 30 days and increased the chance toward 95%, so a long-lived hostage could almost guarantee a
    # repetitive recovery war. The state marker is cleared only when the hostage transitions into a
    # different DDM coercion state.
    if = {
        limit = {
            is_alive = yes
            NOT = { has_character_flag = ddm_writ_retrieval_attempted_state }
            has_variable = ddm_writ_origin_top_liege
            var:ddm_writ_origin_top_liege = {
                is_alive = yes
                is_landed = yes
                is_at_war = no
                is_imprisoned = no
                NOT = { has_character_flag = ddm_kidnap_retrieval_war_cooldown }
            }
            OR = {
                AND = {
                    is_imprisoned = yes
                    has_character_flag = ddm_writ_hostage
                    has_variable = ddm_writ_captor
                    var:ddm_writ_captor = { is_alive = yes }
                }
                AND = {
                    has_variable = ddm_writ_coercion_type
                    has_variable = ddm_writ_coerced_by
                    var:ddm_writ_coerced_by = { is_alive = yes }
                }
            }
        }

        add_character_flag = ddm_writ_retrieval_attempted_state
        save_scope_as = ddm_writ_retrieval_target

        # Identify the ruler whose realm currently contains/controls the target.
        if = {
            limit = { is_imprisoned = yes has_variable = ddm_writ_captor }
            var:ddm_writ_captor = { top_liege = { save_scope_as = ddm_writ_captor_top_liege } }
        }
        else_if = {
            limit = { has_variable = ddm_writ_coerced_by }
            var:ddm_writ_coerced_by = { top_liege = { save_scope_as = ddm_writ_captor_top_liege } }
        }
        var:ddm_writ_origin_top_liege = { save_scope_as = ddm_writ_retrieval_attacker }

        if = {
            limit = {
                exists = scope:ddm_writ_captor_top_liege
                scope:ddm_writ_captor_top_liege = {
                    is_alive = yes
                    is_landed = yes
                    is_at_war = no
                    NOT = { has_character_flag = ddm_retrieval_war_target_cooldown }
                }
                scope:ddm_writ_retrieval_attacker != scope:ddm_writ_captor_top_liege

                # AI rulers only go to war over people with direct political/household importance.
                # The player may still escalate a broader authored Writ dispute.
                OR = {
                    scope:ddm_writ_retrieval_attacker = { is_ai = no }
                    OR = {
                        is_close_family_of = scope:ddm_writ_retrieval_attacker
                        is_spouse_of = scope:ddm_writ_retrieval_attacker
                        is_consort_of = scope:ddm_writ_retrieval_attacker
                        is_heir_of = scope:ddm_writ_retrieval_attacker
                        is_landed = yes
                    }
                }

                # AI does not launch a scripted recovery war into a stronger realm.
                OR = {
                    scope:ddm_writ_retrieval_attacker = { is_ai = no }
                    scope:ddm_writ_retrieval_attacker.current_military_strength >= scope:ddm_writ_captor_top_liege.current_military_strength
                }
            }

            # Reuse the existing DDM kidnapping rule for all autonomous recovery-war escalation.
            # This avoids a hidden second aggressiveness system for Writ Hostages.
            if = {
                limit = { scope:ddm_writ_retrieval_attacker = { is_ai = yes } }
                if = {
                    limit = { has_game_rule = ddm_kidnap_disabled }
                    set_variable = { name = ddm_writ_retrieval_chance value = 0 }
                }
                else_if = {
                    limit = { has_game_rule = ddm_kidnap_player_only }
                    set_variable = { name = ddm_writ_retrieval_chance value = 3 }
                }
                else_if = {
                    limit = { has_game_rule = ddm_kidnap_aggressive_ai }
                    set_variable = { name = ddm_writ_retrieval_chance value = 12 }
                }
                else = {
                    set_variable = { name = ddm_writ_retrieval_chance value = 6 }
                }
            }
            else = {
                set_variable = { name = ddm_writ_retrieval_chance value = 12 }
            }

            if = { limit = { is_close_family_of = scope:ddm_writ_retrieval_attacker } change_variable = { name = ddm_writ_retrieval_chance add = 10 } }
            if = { limit = { is_heir_of = scope:ddm_writ_retrieval_attacker } change_variable = { name = ddm_writ_retrieval_chance add = 15 } }
            if = { limit = { OR = { is_spouse_of = scope:ddm_writ_retrieval_attacker is_consort_of = scope:ddm_writ_retrieval_attacker } } change_variable = { name = ddm_writ_retrieval_chance add = 12 } }
            if = { limit = { is_landed = yes } change_variable = { name = ddm_writ_retrieval_chance add = 8 } }
            if = { limit = { has_variable = ddm_writ_coercion_type } change_variable = { name = ddm_writ_retrieval_chance add = 10 } }

            if = {
                limit = { scope:ddm_writ_retrieval_attacker = { is_ai = yes } has_game_rule = ddm_kidnap_player_only var:ddm_writ_retrieval_chance > 20 }
                set_variable = { name = ddm_writ_retrieval_chance value = 20 }
            }
            else_if = {
                limit = { scope:ddm_writ_retrieval_attacker = { is_ai = yes } has_game_rule = ddm_kidnap_aggressive_ai var:ddm_writ_retrieval_chance > 45 }
                set_variable = { name = ddm_writ_retrieval_chance value = 45 }
            }
            else_if = {
                limit = { scope:ddm_writ_retrieval_attacker = { is_ai = yes } var:ddm_writ_retrieval_chance > 35 }
                set_variable = { name = ddm_writ_retrieval_chance value = 35 }
            }
            else_if = {
                limit = { var:ddm_writ_retrieval_chance > 65 }
                set_variable = { name = ddm_writ_retrieval_chance value = 65 }
            }

            random = {
                chance = var:ddm_writ_retrieval_chance
                # Populate the exact state required by the shared event-only CB. Earlier builds did not
                # do this, so Writ recovery attempts could fail validation or immediately invalidate.
                set_variable = { name = ddm_kidnap_abductor_top_liege value = scope:ddm_writ_captor_top_liege }
                scope:ddm_writ_retrieval_attacker = {
                    set_variable = { name = ddm_kidnap_retrieval_target value = scope:ddm_writ_retrieval_target }
                    if = {
                        limit = { is_ai = no }
                        add_character_flag = { flag = ddm_kidnap_retrieval_war_cooldown years = 5 }
                    }
                    else_if = {
                        limit = { has_game_rule = ddm_kidnap_aggressive_ai }
                        add_character_flag = { flag = ddm_kidnap_retrieval_war_cooldown years = 7 }
                    }
                    else = {
                        add_character_flag = { flag = ddm_kidnap_retrieval_war_cooldown years = 10 }
                    }
                    start_war = { casus_belli = ddm_kidnap_retrieval_cb target = scope:ddm_writ_captor_top_liege }
                }
                scope:ddm_writ_captor_top_liege = {
                    add_character_flag = { flag = ddm_retrieval_war_target_cooldown years = 3 }
                }
            }
            remove_variable = ddm_writ_retrieval_chance
        }
    }
}

# Target scope; scope:ddm_retrieval_restorer is the victorious origin ruler.
# Reverses only political changes explicitly marked as DDM writ coercion.
ddm_restore_writ_coercion_effect = {
    if = {
        limit = {
            has_variable = ddm_writ_origin_top_liege
            var:ddm_writ_origin_top_liege = scope:ddm_retrieval_restorer
            has_variable = ddm_writ_coercion_type
        }
        # 1 — forced courtier: return to the old employer when possible, otherwise to the victorious origin ruler.
        if = {
            limit = { var:ddm_writ_coercion_type = 1 is_landed = no }
            if = {
                limit = { has_variable = ddm_writ_original_employer var:ddm_writ_original_employer = { is_alive = yes } }
                var:ddm_writ_original_employer = { save_scope_as = ddm_writ_restore_employer }
                set_employer = scope:ddm_writ_restore_employer
            }
            else = { set_employer = scope:ddm_retrieval_restorer }
        }
        # 2 — forced vassal: restore old liege, or independence if the victim had none.
        else_if = {
            limit = { var:ddm_writ_coercion_type = 2 is_landed = yes }
            if = {
                limit = { has_variable = ddm_writ_original_liege var:ddm_writ_original_liege = { is_alive = yes is_landed = yes } }
                var:ddm_writ_original_liege = { save_scope_as = ddm_writ_restore_liege }
                create_title_and_vassal_change = { type = swear_fealty save_scope_as = ddm_writ_restore_vassal_change add_claim_on_loss = no }
                change_liege = { liege = scope:ddm_writ_restore_liege change = scope:ddm_writ_restore_vassal_change }
                resolve_title_and_vassal_change = scope:ddm_writ_restore_vassal_change
            }
            else_if = {
                limit = { is_independent_ruler = no }
                create_title_and_vassal_change = { type = independency save_scope_as = ddm_writ_restore_independence_change add_claim_on_loss = no }
                becomes_independent = { change = scope:ddm_writ_restore_independence_change }
                resolve_title_and_vassal_change = scope:ddm_writ_restore_independence_change
            }
        }
        # 3 — forced tributary: end the DDM-created tributary relation.
        else_if = {
            limit = { var:ddm_writ_coercion_type = 3 is_tributary = yes }
            mandala_end_tributary_with_notification_effect = yes
        }
        # 4 — forced abdication: restore only the titles recorded at the moment of coercion.
        else_if = {
            limit = { var:ddm_writ_coercion_type = 4 has_variable_list = ddm_writ_abdicated_titles }
            save_scope_as = ddm_writ_restored_abdicator
            create_title_and_vassal_change = { type = granted save_scope_as = ddm_writ_restore_title_change add_claim_on_loss = no }
            every_in_list = {
                variable = ddm_writ_abdicated_titles
                limit = { exists = holder holder != scope:ddm_writ_restored_abdicator }
                change_title_holder = { holder = scope:ddm_writ_restored_abdicator change = scope:ddm_writ_restore_title_change government_base = scope:ddm_writ_restored_abdicator }
            }
            resolve_title_and_vassal_change = scope:ddm_writ_restore_title_change
        }
        ddm_clear_writ_origin_effect = yes
    }
}
