﻿# On_actions for the Realm Stability mechanic
# This file isolates the realm stability on_action so it can be enabled, disabled,
# or scheduled independently from adventurer logic.

yearly_global_pulse = {
    on_actions = {
        riseandfall_story_world_climate
        # Establish this year's campaign state before individual realms react to it.
        riseandfall_yearly_realm_stability
        riseandfall_clear_unlanded_realm_stability
    }
}

on_game_start_after_lobby = {
    on_actions = {
        riseandfall_story_world_climate
        # Seed the director before initial stability calculations assign roles.
        riseandfall_yearly_realm_stability
        riseandfall_clear_unlanded_realm_stability
    }
}

on_war_won_attacker = {
    on_actions = {
        riseandfall_war_won_attacker
    }
}

on_war_won_defender = {
    on_actions = {
        riseandfall_war_won_defender
    }
}

# React to character death: transfer stability score from predecessor to heir
on_death = {
    on_actions = {
        riseandfall_on_death_stability_inheritance
    }
}

# React to characters gaining titles by inheritance so newly-inherited rulers
# get a computed realm stability value instead of the engine defaulting them to 100.
on_title_gain_inheritance = {
    on_actions = {
        riseandfall_on_title_gain_inheritance
    }
}

on_title_gain = {
    on_actions = {
        riseandfall_on_title_gain_realm_stability_refresh
        riseandfall_peasant_realm_cleanup_on_structure_change
    }
}

# Vanilla supplies root as the former holder and scope:landed_title as the
# title being destroyed. Clear the title-bound campaign ledger before a later
# recreation of the same title can inherit an obsolete collapse arc.
on_title_destroyed = {
    on_actions = {
        riseandfall_clear_destroyed_title_story_collapse
    }
}

on_vassal_gained = {
    on_actions = {
        riseandfall_peasant_realm_cleanup_on_structure_change
    }
}

on_vassal_change = {
    on_actions = {
        riseandfall_peasant_realm_cleanup_on_structure_change
    }
}

riseandfall_on_death_stability_inheritance = {
    # Expected scope: character (who is dying)
    # Root scope: the dying character
    # Available: scope:killer (if killed), player_heir (if exists), primary_heir (if exists)
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
        is_ruler = yes
        has_variable = riseandfall_realm_stability_score
    }
    effect = {
    # Save the dying character as the predecessor for heir to reference
        save_scope_as = predecessor
        set_variable = { name = riseandfall_rs_inheritance_realm_size value = realm_size }
        # If a primary heir exists, transfer stability to them
        if = {
            limit = {
                exists = primary_heir
                primary_heir = { is_alive = yes }
            }
            # Only transfer stability to the primary heir if the heir is strictly LOWER
            # or EQUAL ranked than the predecessor.
            # The game's tier constants map higher numbers -> higher ranks
            # (see common/script_values/00_title_tiers_values.txt: tier_county=2 ... tier_empire=5).
            # Prevent inheritance when the heir's highest_held_title_tier is greater
            # to the predecessor's highest_held_title_tier.
            primary_heir = {
                if = {
                    limit = {
                        OR = {
                            scope:predecessor = { is_landed = no }
                            highest_held_title_tier <= scope:predecessor.highest_held_title_tier
                        }
                        NOT = { has_variable = riseandfall_realm_stability_score }
                    }
                    riseandfall_inherit_stability_score_se = yes
                }
                riseandfall_mark_story_succession_shock_se = yes
                riseandfall_inherit_story_collapse_buildup_se = yes
                riseandfall_mark_story_succession_year_se = yes
            }
        }
        # Also check player_heir if different from primary_heir
        else_if = {
            limit = {
                exists = player_heir
                player_heir = { is_alive = yes }
                player_heir != primary_heir
            }
            # Same guard for player_heir
            player_heir = {
                if = {
                    limit = {
                        # Only inherit stability from a higher or equal-ranked predecessor.
                        highest_held_title_tier <= scope:predecessor.highest_held_title_tier
                        NOT = { has_variable = riseandfall_realm_stability_score }
                    }
                    riseandfall_inherit_stability_score_se = yes
                }
                riseandfall_mark_story_succession_shock_se = yes
                riseandfall_inherit_story_collapse_buildup_se = yes
                riseandfall_mark_story_succession_year_se = yes
            }
        }
    }
}

riseandfall_on_title_gain_inheritance = {
    # Expected scope: character (the inheritor)
    # Available only in on_title_gain_inheritance event: scope:previous_holder and scope:title
    # NOT available in other contexts
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
    }
    effect = {
        # When a landed character inherits a title and doesn't have a stability score yet,
        # check if the previous holder had one and inherit it.
        # This handles title-by-title transfers (e.g., primary title vs vassal titles)
        # IMPORTANT: Do NOT allow a character to inherit stability from same or lower rank rulers
        # (e.g., an emperor should not inherit a count's or king's stability)
        if = {
            limit = {
                NOT = { has_variable = riseandfall_realm_stability_score }
                holds_landed_title = yes
                is_independent_ruler = yes
                exists = scope:previous_holder
                scope:previous_holder = { has_variable = riseandfall_realm_stability_score }
                # Only inherit when the previous holder is higher or equal-ranked than the inheritor.
                # Note: game tier constants map higher numbers -> higher ranks
                # (see common/script_values/00_title_tiers_values.txt: tier_county=2 ... tier_empire=5).
                highest_held_title_tier <= scope:previous_holder.highest_held_title_tier
            }
            # Inherit from the previous holder of this specific title
            scope:previous_holder = { save_scope_as = predecessor }
            riseandfall_inherit_stability_score_se = yes
            riseandfall_mark_story_succession_shock_se = yes
            riseandfall_inherit_story_collapse_buildup_se = yes
            riseandfall_mark_story_succession_year_se = yes
            riseandfall_calculate_realm_stability_se = yes
        }
        else_if = {
            limit = {
                has_variable = riseandfall_realm_stability_score
                holds_landed_title = yes
                is_independent_ruler = yes
                exists = scope:previous_holder
                scope:previous_holder = { has_variable = riseandfall_realm_stability_score }
                NOT = { var:riseandfall_rs_last_stability_merge_predecessor ?= scope:previous_holder }
                # Only merge top-tier realm titles from the inherited ruler.
                # Lower titles under the same inheritance can fire their own title-gain events.
                highest_held_title_tier <= scope:previous_holder.highest_held_title_tier
                exists = scope:title
                scope:title = {
                    tier >= tier_duchy
                    tier = scope:previous_holder.highest_held_title_tier
                }
            }
            # He already has a stability score; merge the inherited realm's stability
            # by the gained title's de jure county share. Only copy secondary history
            # when this inheritance became the ruler's primary title.
            scope:previous_holder = { save_scope_as = predecessor }
            riseandfall_merge_inherited_realm_stability_se = yes
            if = {
                limit = { has_primary_title = scope:title }
                riseandfall_inherit_realm_history_se = yes
                riseandfall_inherit_story_collapse_buildup_se = yes
            }
            riseandfall_mark_story_succession_shock_se = yes
            riseandfall_mark_story_succession_year_se = yes
            riseandfall_calculate_realm_stability_se = yes
        }
        else_if = {
            limit = {
                NOT = { has_variable = riseandfall_realm_stability_score }
                holds_landed_title = yes
                is_independent_ruler = yes
            }
            # No previous holder data or rank check failed; initialize fresh calculation
            riseandfall_calculate_realm_stability_se = yes
        }
    }
}

riseandfall_on_title_gain_realm_stability_refresh = {
    # Expected scope: character (the new title holder)
    # Generic title gains should not inherit or merge predecessor stability;
    # this only initializes stability for newly landed rulers.
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
    }
    effect = {
        if = {
            limit = {
                NOT = { has_variable = riseandfall_realm_stability_score }
                holds_landed_title = yes
                is_independent_ruler = yes
            }
            riseandfall_calculate_realm_stability_se = yes
        }
        else_if = {
            limit = {
                has_variable = riseandfall_realm_stability_score
                holds_landed_title = yes
                is_independent_ruler = yes
                exists = scope:title
                has_primary_title = scope:title
                primary_title = { has_variable = riseandfall_story_title_collapse_pressure }
            }
            # A new ruler who takes the central title reloads its campaign state
            # immediately instead of waiting for the next yearly pulse.
            riseandfall_calculate_realm_stability_se = yes
        }
    }
}

riseandfall_clear_destroyed_title_story_collapse = {
    trigger = {
        OR = {
            scope:landed_title = { has_variable = riseandfall_story_title_collapse_pressure }
            AND = {
                has_variable = riseandfall_story_collapse_pressure
                has_primary_title = scope:landed_title
            }
        }
    }
    effect = {
        if = {
            limit = { scope:landed_title = { has_variable = riseandfall_story_title_collapse_pressure } }
            scope:landed_title = { remove_variable = riseandfall_story_title_collapse_pressure }
        }
        # Do not erase a ruler's active arc when an unrelated spare title dies.
        # The character meter belongs to this destroyed title only if it was primary.
        if = {
            limit = { has_primary_title = scope:landed_title }
            remove_variable = riseandfall_story_collapse_pressure
            remove_variable = riseandfall_story_arc
            remove_variable = riseandfall_story_arc_phase
            remove_variable = riseandfall_story_collapse_gain_last
            remove_character_flag = rf_story_decline_target
        }
    }
}

riseandfall_peasant_realm_cleanup_on_structure_change = {
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
        is_landed = yes
        OR = {
            has_trait = peasant_leader
            has_trait = populist_leader
            AND = {
                exists = liege
                top_liege = {
                    OR = {
                        has_trait = peasant_leader
                        has_trait = populist_leader
                    }
                }
            }
        }
    }
    effect = {
        if = {
            limit = {
                exists = scope:title
                scope:title.tier = tier_county
            }
            scope:title = {
                riseandfall_clear_low_stability_county_modifiers_se = yes
            }
        }
        if = {
            limit = {
                is_landed = yes
                OR = {
                    has_trait = peasant_leader
                    has_trait = populist_leader
                }
            }
            riseandfall_clear_peasant_victory_low_stability_modifiers_se = yes
        }
        else_if = {
            limit = {
                is_landed = yes
                exists = liege
                top_liege = {
                    OR = {
                        has_trait = peasant_leader
                        has_trait = populist_leader
                    }
                }
            }
            top_liege = {
                riseandfall_clear_peasant_victory_low_stability_modifiers_se = yes
            }
        }
    }
}

riseandfall_yearly_realm_stability = {
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
    }
    effect = {
        every_independent_ruler = {
            limit = {
                is_landed = yes
                primary_title.tier >= tier_county
            }
            save_scope_as = independent_ruler
            scope:independent_ruler = {
                riseandfall_legitimate_house_ruler_maintenance_se = yes
                riseandfall_calculate_realm_stability_se = yes
                # Apply warlord legitimacy loss for rulers with warlord vassals
                riseandfall_warlord_legitimacy_loss_se = yes
            }
        }
    }
}

riseandfall_story_world_climate = {
    trigger = {
        has_game_rule = riseandfall_realm_stability_enabled
        OR = {
            has_game_rule = riseandfall_dynamic_story_mode_dynamic
            has_game_rule = riseandfall_dynamic_story_mode_forced
        }
    }
    effect = {
        riseandfall_story_world_climate_se = yes
    }
}

# React to wars being won so we can apply immediate +5/-5 war penalties
riseandfall_war_won_attacker = {
    trigger = { has_game_rule = riseandfall_realm_stability_enabled }
    effect = {
        # Root scope: none; event provides scope:attacker and scope:defender
    # Apply loss to defender. Apply victory effect to attacker only when the
    # war is NOT a peasant rebellion (peasant wars should not count as valid wins).
    # NOTE: war on_actions provide attacker/defender as weak scopes in some contexts.
    # Save them to strong scopes before modifying variables to avoid runtime errors.
    scope:defender = { save_scope_as = rf_defender }
    if = { limit = { exists = scope:rf_defender } scope:rf_defender = { riseandfall_war_loss_se = yes } }
    clear_saved_scope = rf_defender
    if = {
        limit = { scope:war = { NOT = { using_cb = peasant_war } } }
        scope:attacker = { save_scope_as = rf_attacker }
        if = { limit = { exists = scope:rf_attacker } scope:rf_attacker = { riseandfall_war_victory_se = yes } }
        clear_saved_scope = rf_attacker
    }
    }
}

riseandfall_war_won_defender = {
    trigger = { has_game_rule = riseandfall_realm_stability_enabled }
    effect = {
        # Root scope: none; event provides scope:attacker and scope:defender
    # Apply loss to attacker. Apply victory effect to defender only for non-peasant wars
    scope:attacker = { save_scope_as = rf_attacker }
    if = { limit = { exists = scope:rf_attacker } scope:rf_attacker = { riseandfall_war_loss_se = yes } }
    clear_saved_scope = rf_attacker
    if = {
        limit = { scope:war = { NOT = { using_cb = peasant_war } } }
        scope:defender = { save_scope_as = rf_defender }
        if = { limit = { exists = scope:rf_defender } scope:rf_defender = { riseandfall_war_victory_se = yes } }
        clear_saved_scope = rf_defender
    }
    }
}

riseandfall_clear_unlanded_realm_stability = {
    trigger = { has_game_rule = riseandfall_realm_stability_enabled }
    effect = {
        # Clear realm stability variables and modifiers on non-independent characters
        # yearly to fix stale state after land or vassalage changes.
        riseandfall_clear_unlanded_stability_vars_se = yes
    }
}
