﻿##########################
# Rise and Fall - Low Stability yearly roll
# Runs once per ruler on that character's random yearly pulse and computes a tier-based curved chance from stability score.
# If the random check succeeds, trigger an event (riseandfall.1001 - warlord).

# Expected scope: landed ruler. Store the reduction on the title so it survives succession.
riseandfall_set_low_stability_cooldown_se = {
    if = {
        limit = { exists = primary_title }
        primary_title = {
            # A completed incident starts at 100% reduction. The yearly roll
            # lowers this by 10 points, so the first following year has a 90%
            # reduction and the tenth following year is fully recovered.
            set_variable = { name = rf_low_stability_cooldown value = 100 }
        }
    }
}

riseandfall_low_stability_roll_se = {
    # Perform computations inside the saved ruler scope so character variables resolve correctly.
        scope:ruler_low_stability = {
            # Recover 10 percentage points per year before calculating this
            # year's chance. Remove the marker at zero so the cooldown expires.
            if = {
                limit = {
                    exists = primary_title
                    primary_title = { has_variable = rf_low_stability_cooldown }
                }
                primary_title = {
                    change_variable = { name = rf_low_stability_cooldown add = -10 }
                    clamp_variable = { name = rf_low_stability_cooldown min = 0 max = 100 }
                    if = {
                        limit = { var:rf_low_stability_cooldown <= 0 }
                        remove_variable = rf_low_stability_cooldown
                    }
                }
            }
            # Coalition availability enters an independent-ruler iterator, so
            # preserve the incident ruler before that iterator changes scope.
            save_scope_as = coalition_target
            # Repair interrupted Coalition state before evaluating this year's incident.
            riseandfall_coalition_clear_stale_target_state_se = yes
            # Coalition pressure is territory-based and must be refreshed before
            # selector-facing triggers inspect the stored percentage.
            riseandfall_coalition_calculate_periphery_se = yes
            # Ensure a default stability score exists so scripts don't error when it's missing
            if = { limit = { NOT = { has_variable = riseandfall_realm_stability_score } } set_variable = { name = riseandfall_realm_stability_score value = 50 } }
            if = {
                limit = {
                    exists = primary_title
                }
                # Compute chance with a curved (approx power 1.5) formula based on highest held title tier.
                # Thresholds: county = 30, duchy = 35, kingdom = 40, empire = 45, hegemony = 50.
                # Approach: tmp_diff = max(0, threshold - stability_score)
                # Chance ~= floor( (tmp_diff^2 * 100) / (threshold^2) ); minimum 1% when tmp_diff > 0.
                set_variable = { name = stability_threshold value = 30 }
                if = { limit = { highest_held_title_tier >= tier_duchy } set_variable = { name = stability_threshold value = 35 } }
                if = { limit = { highest_held_title_tier >= tier_kingdom } set_variable = { name = stability_threshold value = 40 } }
                if = { limit = { highest_held_title_tier >= tier_empire } set_variable = { name = stability_threshold value = 45 } }
                if = { limit = { highest_held_title_tier >= tier_hegemony } set_variable = { name = stability_threshold value = 50 } }

                set_variable = { name = tmp_diff value = 0 }
                change_variable = { name = tmp_diff add = var:riseandfall_realm_stability_score }
                change_variable = { name = tmp_diff multiply = -1 }
                change_variable = { name = tmp_diff add = var:stability_threshold }
                clamp_variable = { name = tmp_diff min = 0 max = 50 }

                set_variable = { name = tmp_chance value = 0 }
                # If stability > threshold, chance should be 0%
                if = {
                    limit = { var:riseandfall_realm_stability_score > var:stability_threshold }
                    set_variable = { name = tmp_chance value = 0 }
                }
                else = {
                    # tmp_sq = tmp_diff^2
                    set_variable = { name = tmp_sq value = var:tmp_diff }
                    change_variable = { name = tmp_sq multiply = var:tmp_diff }

                    # Scale to percentage: (tmp_sq * 100) / (threshold^2)
                    set_variable = { name = tmp_chance value = var:tmp_sq }
                    change_variable = { name = tmp_chance multiply = 100 }
                    change_variable = { name = tmp_chance divide = var:stability_threshold }
                    change_variable = { name = tmp_chance divide = var:stability_threshold }

                    # Ensure at least 1% when tmp_diff > 0
                    if = { limit = { AND = { var:tmp_diff > 0 var:tmp_chance < 1 } } set_variable = { name = tmp_chance value = 1 } }
                }

                # Allow full 0..100% range so 0 stability can be an immediate crisis.
                clamp_variable = { name = tmp_chance min = 0 max = 100 }

                if = {
                    limit = {
                        has_variable = riseandfall_story_successor_grace
                        var:riseandfall_story_successor_grace > 0
                        var:riseandfall_realm_stability_score >= 20
                    }
                    change_variable = { name = tmp_chance divide = 2 }
                }

                # Scale the normal chance by the title's remaining recovery.
                # A 90% cooldown reduction leaves 10% of the normal chance.
                if = {
                    limit = {
                        exists = primary_title
                        primary_title = { has_variable = rf_low_stability_cooldown }
                    }
                    set_variable = { name = tmp_cooldown_scale value = 100 }
                    change_variable = { name = tmp_cooldown_scale add = primary_title.var:rf_low_stability_cooldown }
                    change_variable = { name = tmp_cooldown_scale multiply = -1 }
                    clamp_variable = { name = tmp_cooldown_scale min = 0 max = 100 }
                    change_variable = { name = tmp_chance multiply = var:tmp_cooldown_scale }
                    change_variable = { name = tmp_chance divide = 100 }
                }

                clamp_variable = { name = tmp_chance min = 0 max = 100 }

                # Store the calculated chance on the character for tooltip display (persists until next yearly update)
                set_variable = { name = riseandfall_low_stability_chance value = var:tmp_chance }
                if = {
                    limit = { var:riseandfall_low_stability_chance > 100 }
                    set_variable = { name = riseandfall_low_stability_chance value = 100 }
                }

                # Roll once for the independent ruler. If it succeeds, notify the liege and add stability
                random = {
                    chance = var:tmp_chance
                    # Trigger a random low stability event
                    riseandfall_low_stability_random_event = yes
                }
            }
            else = {
                # If on cooldown, chance is 0
                set_variable = { name = riseandfall_low_stability_chance value = 0 }
                if = {
                    limit = { var:riseandfall_low_stability_chance > 100 }
                    set_variable = { name = riseandfall_low_stability_chance value = 100 }
                }
            }
        }
    }

##########################
# Rise and Fall - Low Stability Random Event Selector
# Randomly selects between warlord uprising, peasant unrest, and puppet master offer

riseandfall_low_stability_random_event = {
    # Keep selector simple: each entry has its own availability trigger.
    # random_list excludes entries whose trigger fails, so valid entries are rerolled automatically.
    if = {
        limit = {
            OR = {
                riseandfall_low_stability_warlord_available_trigger = yes
                riseandfall_low_stability_palace_coup_available_trigger = yes
                riseandfall_low_stability_realm_split_available_trigger = yes
                riseandfall_low_stability_nationalist_revolt_available_trigger = yes
                riseandfall_low_stability_vassal_crisis_available_trigger = yes
                riseandfall_low_stability_authority_collapse_available_trigger = yes
                riseandfall_low_stability_coalition_available_trigger = yes
            }
        }
        random_list = {
            # Story Mode does not fire a separate scripted crisis. Once an active
            # Declining Power reaches its crisis phase, it instead makes the
            # existing low-stability selector prefer the failure that matches the
            # realm's actual fault line. Generic entries below remain fallbacks.
            900 = {
                trigger = {
                    has_character_flag = rf_story_decline_target
                    has_variable = riseandfall_story_arc
                    var:riseandfall_story_arc = 1
                    has_variable = riseandfall_story_arc_phase
                    var:riseandfall_story_arc_phase >= 2
                    riseandfall_low_stability_vassal_crisis_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1002 }
            }
            900 = {
                trigger = {
                    has_character_flag = rf_story_decline_target
                    has_variable = riseandfall_story_arc
                    var:riseandfall_story_arc = 2
                    has_variable = riseandfall_story_arc_phase
                    var:riseandfall_story_arc_phase >= 2
                    riseandfall_low_stability_nationalist_revolt_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1001 }
            }
            1200 = {
                trigger = {
                    has_character_flag = rf_story_decline_target
                    has_variable = riseandfall_story_arc
                    OR = {
                        var:riseandfall_story_arc = 3
                        var:riseandfall_story_arc = 4
                    }
                    has_variable = riseandfall_story_arc_phase
                    var:riseandfall_story_arc_phase >= 3
                    riseandfall_low_stability_realm_split_available_trigger = yes
                }
                trigger_event = { id = realm_split.1001 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_warlord_high
                    riseandfall_low_stability_warlord_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = warlord.1001 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_warlord_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_warlord_low }
                    riseandfall_low_stability_warlord_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = warlord.1001 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_warlord_low
                    riseandfall_low_stability_warlord_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = warlord.1001 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_palace_coup_high
                    riseandfall_low_stability_palace_coup_available_trigger = yes
                }
                trigger_event = { id = palace_coup.1001 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_palace_coup_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_palace_coup_low }
                    riseandfall_low_stability_palace_coup_available_trigger = yes
                }
                trigger_event = { id = palace_coup.1001 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_palace_coup_low
                    riseandfall_low_stability_palace_coup_available_trigger = yes
                }
                trigger_event = { id = palace_coup.1001 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_realm_split_high
                    riseandfall_low_stability_realm_split_available_trigger = yes
                }
                trigger_event = { id = realm_split.1001 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_realm_split_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_realm_split_low }
                    riseandfall_low_stability_realm_split_available_trigger = yes
                }
                trigger_event = { id = realm_split.1001 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_realm_split_low
                    riseandfall_low_stability_realm_split_available_trigger = yes
                }
                trigger_event = { id = realm_split.1001 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_nationalist_revolt_high
                    riseandfall_low_stability_nationalist_revolt_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1001 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_nationalist_revolt_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_nationalist_revolt_low }
                    riseandfall_low_stability_nationalist_revolt_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1001 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_nationalist_revolt_low
                    riseandfall_low_stability_nationalist_revolt_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1001 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_vassal_crisis_high
                    riseandfall_low_stability_vassal_crisis_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1002 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_vassal_crisis_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_vassal_crisis_low }
                    riseandfall_low_stability_vassal_crisis_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1002 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_vassal_crisis_low
                    riseandfall_low_stability_vassal_crisis_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1002 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_authority_collapse_high
                    riseandfall_low_stability_authority_collapse_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1003 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_authority_collapse_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_authority_collapse_low }
                    riseandfall_low_stability_authority_collapse_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1003 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_authority_collapse_low
                    riseandfall_low_stability_authority_collapse_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = authority_collapse.1003 }
            }
            300 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_coalition_high
                    riseandfall_low_stability_coalition_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = coalition.1001 }
            }
            100 = {
                trigger = {
                    NOT = { exists = global_var:riseandfall_low_stability_event_coalition_high }
                    NOT = { exists = global_var:riseandfall_low_stability_event_coalition_low }
                    riseandfall_low_stability_coalition_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = coalition.1001 }
            }
            33 = {
                trigger = {
                    exists = global_var:riseandfall_low_stability_event_coalition_low
                    riseandfall_low_stability_coalition_available_trigger = yes
                }
                riseandfall_story_collapse_relief_se = yes
                trigger_event = { id = coalition.1001 }
            }
        }
    }
}
