﻿# Sets the scoped (playable) character's Spiritual Fulfillment to $TARGET$ (-100 to 100).
# change_spiritual_fulfillment is multiplied by the character's gain/loss modifiers, which script cannot read.
# The first step in each direction is a 1-point probe that measures that direction's multiplier; later steps
# divide the remaining difference by the measured multiplier. Stops when within 1 point, after two steps in a
# row without progress (e.g. both multipliers >= 2 make odd differences unreachable), when a step does not move
# the value at all (e.g. Divine Grace blocking losses), or after 8 steps. Runs only when a Stats tab button is clicked.
DI_bga_set_fulfillment_effect = {
    set_variable = { name = DI_bga_ful_target value = $TARGET$ }
    if = {
        limit = { var:DI_bga_ful_target > 100 }
        set_variable = { name = DI_bga_ful_target value = 100 }
    }
    else_if = {
        limit = { var:DI_bga_ful_target < -100 }
        set_variable = { name = DI_bga_ful_target value = -100 }
    }
    set_variable = { name = DI_bga_ful_steps value = 0 }
    set_variable = { name = DI_bga_ful_no_progress value = 0 }
    while = {
        limit = {
            var:DI_bga_ful_steps < 8
            DI_bga_ful_absdiff_value >= 1
            NOT = { has_variable = DI_bga_ful_stop }
        }
        change_variable = { name = DI_bga_ful_steps add = 1 }
        set_variable = { name = DI_bga_ful_before value = spiritual_fulfillment }
        set_variable = { name = DI_bga_ful_last_absdiff value = DI_bga_ful_absdiff_value }
        if = {
            limit = { DI_bga_ful_diff_value > 0 }
            if = {
                limit = { has_variable = DI_bga_ful_gain_ratio }
                set_variable = { name = DI_bga_ful_request value = DI_bga_ful_gain_request_value }
            }
            else = {
                set_variable = { name = DI_bga_ful_request value = 1 }
            }
            change_spiritual_fulfillment = { value = var:DI_bga_ful_request }
            if = {
                limit = { DI_bga_ful_measured_value > 0 }
                set_variable = { name = DI_bga_ful_gain_ratio value = DI_bga_ful_ratio_value }
            }
            else = {
                set_variable = DI_bga_ful_stop
            }
        }
        else = {
            if = {
                limit = { has_variable = DI_bga_ful_loss_ratio }
                set_variable = { name = DI_bga_ful_request value = DI_bga_ful_loss_request_value }
            }
            else = {
                set_variable = { name = DI_bga_ful_request value = -1 }
            }
            change_spiritual_fulfillment = { value = var:DI_bga_ful_request }
            if = {
                limit = { DI_bga_ful_measured_value < 0 }
                set_variable = { name = DI_bga_ful_loss_ratio value = DI_bga_ful_ratio_value }
            }
            else = {
                set_variable = DI_bga_ful_stop
            }
        }
        # An overshoot is recoverable once the other direction is measured, so only stop
        # after two consecutive steps that do not get closer to the target.
        if = {
            limit = { DI_bga_ful_absdiff_value >= var:DI_bga_ful_last_absdiff }
            change_variable = { name = DI_bga_ful_no_progress add = 1 }
            if = {
                limit = { var:DI_bga_ful_no_progress >= 2 }
                set_variable = DI_bga_ful_stop
            }
        }
        else = {
            set_variable = { name = DI_bga_ful_no_progress value = 0 }
        }
    }
    remove_variable = DI_bga_ful_target
    remove_variable = DI_bga_ful_gain_ratio
    remove_variable = DI_bga_ful_loss_ratio
    remove_variable = DI_bga_ful_steps
    remove_variable = DI_bga_ful_no_progress
    remove_variable = DI_bga_ful_before
    remove_variable = DI_bga_ful_last_absdiff
    remove_variable = DI_bga_ful_request
    remove_variable = DI_bga_ful_stop
}
