local Weapon_System     = GetSelf()
dofile(LockOn_Options.common_script_path.."devices_defs.lua")
--dofile(LockOn_Options.script_path.."Systems/stores_config.lua")
dofile(LockOn_Options.script_path.."cockpit_cfg.lua")
dofile(LockOn_Options.script_path.."command_defs.lua")
dofile(LockOn_Options.script_path.."utils.lua")
dofile(LockOn_Options.script_path.."devices.lua")
dofile(LockOn_Options.script_path.."Systems/device_header.lua")
dofile(LockOn_Options.script_path.."Systems/electric_system_api.lua")

-- 加载 TOF 计算器Time of Flight（飞行实际，即导弹预计命中时间）
local TOFCalc = dofile(LockOn_Options.script_path.."Systems/TOFCalculator.lua")
-- 加载 DLZ 计算器DLZ(动态发射区)
local DLZCalc = dofile(LockOn_Options.script_path.."Systems/DLZCalculator.lua")-- 替换为新版动态DLZ引擎
dofile(LockOn_Options.common_script_path .. "../../../Database/wsTypes.lua")
local avSimplestWeaponSystem = nil
if not (USE_EXT_DLL and Type) then
    package.cpath 			= package.cpath..";".. LockOn_Options.script_path.. "..\\..\\bin\\?.dll"
    avSimplestWeaponSystem = require('avSimplestWeaponSystem')
	--Log_and_print("package avSimplestWeaponSystem")
end

local gunFire = 0
local gunFireTime = 0
local unlimited_weapons = false
local weaponLoading = false
local loadStationIdx = 0
local launchAuthorization = false
local gunPodIdx = {}

local update_time_step = 0.02  --每秒50次刷新
make_default_activity(update_time_step)
local sensor_data = get_base_data()
--------------------------------------------------------------------------------
--红外弹
--------------------------------------------------------------------------------
-- 获取选定状态
local ir_selected = 0

--------------------------------------------------------------------------------
--红外弹句柄
--------------------------------------------------------------------------------
-- 是否锁定
local ir_missile_lock_param = get_param_handle("WS_IR_MISSILE_LOCK")
-- 锁定的红外目标的高程和方向
local ir_missile_az_param = get_param_handle("WS_IR_MISSILE_TARGET_AZIMUTH")
local ir_missile_el_param = get_param_handle("WS_IR_MISSILE_TARGET_ELEVATION")
--------------------------------------------------------------------------------
-- 选定的武器射程
local dlz_min_param = get_param_handle("WS_DLZ_MIN")
local dlz_max_param = get_param_handle("WS_DLZ_MAX")
-- DCS系统给定的发射许可（未使用）
local dlz_authorized_param = get_param_handle("WS_DLZ_AUTHORIZED")
--------------------------------------------------------------------------------
-- 动态 DLZ 句柄
--------------------------------------------------------------------------------
-- 动态 DLZ发射许可（未使用）
local dlz_auth_dyn = get_param_handle("WS_DLZ_AUTH_DYN")
-- 动态发射区 公里
local dlz_min_dyn = get_param_handle("WS_DLZ_MIN_DYN")
local dlz_best_dyn = get_param_handle("WS_DLZ_BEST_DYN")
local dlz_max_dyn = get_param_handle("WS_DLZ_MAX_DYN")
-- 动态拦截余量 公里/海里
local dlz_margin_dyn    = get_param_handle("WS_DLZ_MARGIN_DYN")
local dlz_margin_dyn_NM = get_param_handle("WS_DLZ_MARGIN_DYN_NM")
-- 动态发射区 海里
local dlz_min_dyn_NM	= get_param_handle("WS_DLZ_MIN_DYN_NM") -- nm
local dlz_best_dyn_NM	= get_param_handle("WS_DLZ_BEST_DYN_NM") -- nm
local dlz_max_dyn_NM	= get_param_handle("WS_DLZ_MAX_DYN_NM") -- nm
--------------------------------------------------------------------------------
local gun_piper_available_param = get_param_handle('WS_GUN_PIPER_AVAILABLE')
local gun_piper_az_param = get_param_handle('WS_GUN_PIPER_AZIMUTH')
local gun_piper_el_param = get_param_handle('WS_GUN_PIPER_ELEVATION')
local gun_piper_span_param = get_param_handle('WS_GUN_PIPER_SPAN')
--------------------------------------------------------------------------------
-- 目标距离
--------------------------------------------------------------------------------
-- 海里
local target_range_param_NM	= get_param_handle("TARGET_RANGE_NM")   -- nm
-- 系统给定的目标距离 米
local target_range_param = get_param_handle('WS_TARGET_RANGE')
local target_span_param = get_param_handle('WS_TARGET_SPAN')
--------------------------------------------------------------------------------
-- 红外弹导引头相关
-- 方位角
local ir_missile_des_az_param = get_param_handle("WS_IR_MISSILE_SEEKER_DESIRED_AZIMUTH")
-- 高程
local ir_missile_des_el_param = get_param_handle("WS_IR_MISSILE_SEEKER_DESIRED_ELEVATION")

local ir_seek_az_offset = 0
local ir_seek_el_offset = 0
local ir_seek_az_limit = {-3,3}
local ir_seek_el_limit = {-3,3}
local ir_seek_el = 0
local ir_seek_az = 0
local ir_seek_scan_speed = update_time_step*10
local ir_seek_step_time = 0

local ccrp_status = false

-- 获取仪表weaponpage句柄

Weapon_System:listen_command(Keys.WeaponSelectNext)
Weapon_System:listen_command(Keys.WeaponLaunch)
Weapon_System:listen_command(Keys.DropChaff)
Weapon_System:listen_command(Keys.DropChaffAndFlare)
Weapon_System:listen_command(Keys.DropFlare)
Weapon_System:listen_command(Keys.A2A)
Weapon_System:listen_command(Keys.A2G)
Weapon_System:listen_command(Keys.GunMode)
Weapon_System:listen_command(Keys.ActiveJamming)
Weapon_System:listen_command(Keys.PlaneWingtipSmokeOnOff)
Weapon_System:listen_command(Keys.EmergJettion)
Weapon_System:listen_command(Keys.masterArm)
Weapon_System:listen_command(Keys.SwitchMasterArm)
Weapon_System:listen_command(Keys.PlaneAHCPMasterArm)
Weapon_System:listen_command(Keys.PlaneAHCPMasterSafe)

Weapon_System:listen_event(CptEvntNames.weaponRearmComplete)
Weapon_System:listen_event(CptEvntNames.weaponRearmFirstStep)
Weapon_System:listen_event(CptEvntNames.weaponRearmSingleStepComplete)
Weapon_System:listen_event(CptEvntNames.unlimitedWeaponStationRestore)
Weapon_System:listen_event(CptEvntNames.initChaffFlarePayload)

terrainAirdromes = get_terrain_related_data("Airdromes")

local A2A_R = {'{J20A_PL17},{BayArm_J20_PL-17_x4},{J20A_PL15},J20_PL-15_DUAL,BayArm_J20_PL-15_DUAL,DIS_PL-12'}
local A2A_IR = {'{PLAAF_PL-10E},{BayArm_PLAAF_PL-10E_x4}'}

local master_Arm = 0

local weapon_name = {
	['DIS_LD-10'] = '雷电10',
	['DIS_LD-10_DUAL_L'] = '雷电-10',
	['{J20A_CM102A}'] = 'CM102A',
	['J20_CM102A_DUAL'] = 'CM-102A',
	['DIS_PL-12'] = '霹雳12',
	['DIS_PL-12_DUAL_L'] = '霹雳-12',
	['{J20A_PL17}'] = '霹雳17',
	['{BayArm_J20_PL-17_x4}'] = '霹雳-17',
	['{J20A_PL15}'] = '霹雳15',
	['J20_PL-15_DUAL'] = '霹雳-15',
    ['BayArm_J20_PL-15_DUAL'] = '霹雳-15',
    ['{PLAAF_PL-10E}'] = '霹雳10E',
	['{BayArm_PLAAF_PL-10E_x4}'] = '霹雳-10E',
    ['DIS_GBU_12'] = 'GBU-12',
    ['DIS_MK_20'] = 'MK-20',
	['J_20A_AGM-65E'] = 'AGM-65E',
    ['DIS_DF4B_YJ12'] = '鹰击-12',
	['DIS_GDJ_YJ83K'] = '鹰击-83',
    ['J20C_Laser_Cannon_POD'] = '激光炮',
    ['J20C_EML_POD'] = '电磁线圈炮'
}


local snd_list = {}
local function initSnd()
    local sndHeadPhonehost = create_sound_host("COCKPIT_SIDEWINDER", "HEADPHONES", 0, 0, 0)
    local sndhost = create_sound_host("COCKPIT", "3D", 0, 0, 0)
    snd_list.sidewinder_high = sndHeadPhonehost:create_sound("Aircrafts/J-20A/Cockpit/TargetLock")
    snd_list.sidewinder_high:update(1,1,1)
    snd_list.sidewinder_low = sndHeadPhonehost:create_sound("Aircrafts/J-20A/Cockpit/TargetTrack")
    snd_list.sidewinder_low:update(1,1,1)
    snd_list.sidewinder_quiet = sndHeadPhonehost:create_sound("Aircrafts/Cockpits/SidewinderLowQuiet")
    snd_list.sidewinder_quiet:update(1,1,1)
    snd_list.msl_launch_in = sndhost:create_sound("Weapons/MissileShootIn")
    snd_list.drop_weapon = sndhost:create_sound("Aircrafts/DropWeaponIn")
    snd_list.flare_snd = sndhost:create_sound("Aircrafts/Cockpits/FlareIn")
    snd_list.chaff_snd = sndhost:create_sound("Weapons/Snare")
end
local t_hdg_h = get_param_handle('HDG_DEG')
local WPT_data = {}
local ATK_WPT_data = {}
local atk_wpt_h = get_param_handle('ATK_WPT')
local maxRange_h = get_param_handle('MAX_RANGE')
local function initWPTs()
    for i = 1, 100, 1 do
        WPT_data[#WPT_data+1] = {
            N_LAT = get_param_handle(string.format('WPT_%02.0f_NEXT_REL_LAT',i)),
            N_LON = get_param_handle(string.format('WPT_%02.0f_NEXT_REL_LON',i)),
            NEXT = get_param_handle(string.format('WPT_%02.0f_NEXT',i)),
            LAT = get_param_handle(string.format('WPT_%02.0f_LAT',i)),
            LON = get_param_handle(string.format('WPT_%02.0f_LON',i)),
            NUM = get_param_handle(string.format('WPT_%02.0f_NUM',i)),
            ALT = get_param_handle(string.format('WPT_%02.0f_ALT',i)),
            ALT_TYPE = get_param_handle(string.format('WPT_%02.0f_ALT_TYPE',i)),
            SPD = get_param_handle(string.format('WPT_%02.0f_SPD',i)),
            TYPE = get_param_handle(string.format('WPT_%02.0f_TYPE',i)),
        }
    end
end

local params_h = {
    CHAFF_QTY = {get_param_handle('CHAFF_QTY'),0},
    FLARE_QTY = {get_param_handle('FLARE_QTY'),0},
	MASTER_MODE = {get_param_handle('MASTER_MODE'),0},
    ATK_MODE  = {get_param_handle('ATK_MODE'),0},--0:导航,1:AA,2:AG
    WPN_ROOM_STATUS = {get_param_handle('WPN_ROOM_STATUS'),0},
	PL17_COUNT  = {get_param_handle('PL17_COUNT'),0},
    PL15_COUNT  = {get_param_handle('PL15_COUNT'),0},
    PL12_COUNT  = {get_param_handle('PL12_COUNT'),0},
    PL10E_COUNT = {get_param_handle('PL10E_COUNT'),0},
    LD10_COUNT  = {get_param_handle('LD10_COUNT'),0},
	CM102_COUNT = {get_param_handle('CM102_COUNT'),0},
    AGM65_COUNT = {get_param_handle('AGM65_COUNT'),0},
    GBU12_COUNT = {get_param_handle('GBU12_COUNT'),0},
    TARGET_ROUND_DIS_ENABLE = {get_param_handle('TARGET_ROUND_DIS_ENABLE'),0},
    IR_SEEK_RANGE_DIS = {get_param_handle('IR_SEEK_RANGE_DIS'),0},
    TARGET_ROUND_X = {get_param_handle('TARGET_ROUND_X'),0},
    TARGET_ROUND_Y = {get_param_handle('TARGET_ROUND_Y'),0},
    HMD_TARGET_ROUND_DIS_ENABLE = {get_param_handle('HMD_TARGET_ROUND_DIS_ENABLE'),0},
    HMD_TARGET_ROUND_X = {get_param_handle('HMD_TARGET_ROUND_X'),0},
    HMD_TARGET_ROUND_Y = {get_param_handle('HMD_TARGET_ROUND_Y'),0},
    WEAPON_NAME  = {get_param_handle('WEAPON_NAME'),''},
    WEAPON_COUNT = {get_param_handle('WEAPON_COUNT'),0},
    WEAPON_DIS = {get_param_handle('WEAPON_NAME_DIS'),0},
    PYLON_IDX = {get_param_handle('PYLON_IDX'),0},
    CCIP_DIS_ENABLE = {get_param_handle('CCIP_DIS_ENABLE'),0},
    CCIP_Y = {get_param_handle('CCIP_Y'),0},
    CCIP_X = {get_param_handle('CCIP_X'),0},
    CCRP_DIS_ENABLE = {get_param_handle('CCRP_DIS_ENABLE'),0},
    CCRP_TIME = {get_param_handle('CCRP_TIME'),-1},
    CCRP_TIME_MAX_RANGE = {get_param_handle('CCRP_TIME_MAX_RANGE'),-1},
    CCRP_TIME_TO_IMPACT = {get_param_handle('CCRP_TIME_TO_IMPACT'),-1},
    CCRP_Y = {get_param_handle('CCRP_Y'),0},
    CCRP_X = {get_param_handle('CCRP_X'),0},
    ATK_WPT_MAX = {get_param_handle('ATK_WPT_MAX'),0},
    ECM_STATUS = {get_param_handle('ECM_STATUS'),0},
    IR_SEEK_LIMIT = {get_param_handle('IR_SEEK_LIMIT'),0},
    GUN_MODE = {get_param_handle('GUN_MODE'),0},
    GUN_TYPE = {get_param_handle('GUN_TYPE'),0},
    LASER_GUN_CD1 = {get_param_handle('LASER_GUN_CD1'),0,0,update_time_step,0,10},
    LASER_GUN_CD2 = {get_param_handle('LASER_GUN_CD2'),0,0,update_time_step,0,10},
    LASER_GUN_CHARGE = {get_param_handle('LASER_GUN_CHARGE'),0,0,update_time_step,0,3},
    CURRENT_GUN_IDX = {get_param_handle('CURRENT_GUN_IDX'),0},
    LaserCannonAmmo_L = {get_param_handle('LaserCannonAmmo_L'),0},
    LaserCannonAmmo_R = {get_param_handle('LaserCannonAmmo_R'),0},
    GUN_NAME = {get_param_handle('GUN_NAME'),''},
    GUN_CCIP_DIS_ENABLE = {get_param_handle('GUN_CCIP_DIS_ENABLE'),0},
    GUN_CCIP_X = {get_param_handle('GUN_CCIP_X'),0},
    GUN_CCIP_Y = {get_param_handle('GUN_CCIP_Y'),0},
    GUN_COUNT = {get_param_handle('GUN_COUNT'),648}
}

local hmdType_h = get_param_handle('HMD_TYPE')
local head_el = get_param_handle('HEAD_EL')
local head_az = get_param_handle('HEAD_AZ')
local store = 7
if Type then
    store = 11
end
for _i = 0, store, 1 do
    local i = _i + 1
    local k = string.format('MSL_%.0f_COUNT',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_USING',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_SELECTED',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_PL12',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_LD10',i)
    params_h[k] = {get_param_handle(k),0}
	k = string.format('MSL_%.0f_PL17',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_PL15',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_PL10E',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_BOMB',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_AGM65E',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_YJ12',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_YJ83',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_GUNPOD',i)
    params_h[k] = {get_param_handle(k),0}
    k = string.format('MSL_%.0f_CM102',i)
    params_h[k] = {get_param_handle(k),0}
end

local aircraftArgVal = {
    hideMainRoom={525,0,0.05},
    mainDoor={526,0,0.1},
    rightDoor={527,0,0.05},
    leftDoor={528,0,0.05}
}

local pylonData = {}
local groupWeaponId = {
    [1] = {maxType = 0},
    [2] = {maxType = 0}
}
--[[local function updatePylonInfo()
    -- 重置外部变量
    pylonData = {}
    groupWeaponId[1] = { maxType = 0 }
    groupWeaponId[2] = { maxType = 0 }
    gunPodIdx = {}

    -- 弹种计数
    local gbu12, ld10, cm102 = 0, 0, 0
    local pl10e, pl12, pl15, pl17 = 0, 0, 0, 0

    for i = 0, store do
        local station = Weapon_System:get_station_info(i)
        if station then
            local ws = station.weapon

            -- 跳过挂架本身 (level1=1, level2=3, level3=43)
            if not (ws.level1 == 1 and ws.level2 == 3 and ws.level3 == 43) then
                local idx = i + 1
                pylonData[idx] = station

                local clsID = station.CLSID
                local cnt   = station.count or 0

                -- 统计弹种
                if     clsID == 'DIS_PL-12' then
                    pl12 = pl12 + cnt
                elseif clsID == 'DIS_LD-10'
                   or clsID == 'DIS_LD-10_DUAL_L' then
                    ld10 = ld10 + cnt
                elseif clsID == '{J20A_CM102A}' then
                    cm102 = cm102 + cnt
                elseif clsID == 'DIS_GBU_12' then
                    gbu12 = gbu12 + cnt
                elseif clsID == '{PLAAF_PL-10E}'
                   or clsID == '{BayArm_PLAAF_PL-10E_x4}' then
                    pl10e = pl10e + cnt
                elseif clsID == '{J20A_PL15}'
                   or clsID == 'J20_PL-15_DUAL'
                   or clsID == 'BayArm_J20_PL-15_DUAL' then
                    pl15 = pl15 + cnt
                elseif clsID == '{J20A_PL17}'
                   or clsID == '{BayArm_J20_PL-17_x4}' then
                    pl17 = pl17 + cnt
                end

                -- 分组：A2A / Gunpod / A2G
                local key = string.format('%d%d%d%d',
                              ws.level1, ws.level2, ws.level3, ws.level4)

                if ws.level1 == 4 and ws.level2 == 4 and ws.level3 == 7 then
                    -- A2A
                    if not groupWeaponId[1][key] then
                        groupWeaponId[1][key] = {}
                        groupWeaponId[1][#groupWeaponId[1] + 1] = key
                        groupWeaponId[1].maxType = groupWeaponId[1].maxType + 1
                    end
                    table.insert(groupWeaponId[1][key], idx)

                elseif ws.level1 == 4 and ws.level2 == 6 and ws.level3 == 10 then
                    -- Gunpod
                    table.insert(gunPodIdx, idx)

                else
                    -- A2G
                    if not groupWeaponId[2][key] then
                        groupWeaponId[2][key] = {}
                        groupWeaponId[2][#groupWeaponId[2] + 1] = key
                        groupWeaponId[2].maxType = groupWeaponId[2].maxType + 1
                    end
                    table.insert(groupWeaponId[2][key], idx)
                end
            end
        end
    end

    -- 写回参数句柄
    params_h.PL17_COUNT[2]  = pl17
    params_h.PL15_COUNT[2]  = pl15
    params_h.PL12_COUNT[2]  = pl12
    params_h.PL10E_COUNT[2] = pl10e
    params_h.GBU12_COUNT[2] = gbu12
    params_h.LD10_COUNT[2]  = ld10
    params_h.CM102_COUNT[2] = cm102
end]]

local function updatePylonInfo()
    pylonData = {}
    groupWeaponId[1] = {maxType = 0} -- maxType是用来计数同一个攻击模式下导弹种类数量的
    groupWeaponId[2] = {maxType = 0}
    local gbu12 = 0
    local ld10  = 0
	local cm102 = 0
    local pl10e = 0
    local pl12  = 0
    local pl15  = 0
	local pl17  = 0
    local agm65 = 0
    gunPodIdx   = {}
    for i = 0, store, 1 do
        local station = Weapon_System:get_station_info(i)
        if station~=nil then
            local wsType = station.weapon
            if not (wsType.level1 == 1 and wsType.level2 == 3 and wsType.level3 == 43) then
                pylonData[i+1] = station
                local clsID = pylonData[i + 1].CLSID
                if clsID == 'DIS_PL-12' then
                    pl12 = pl12 + pylonData[i + 1].count
                elseif clsID == 'DIS_LD-10' or clsID == 'DIS_LD-10_DUAL_L' then
                    ld10 = ld10 + pylonData[i + 1].count
				elseif clsID == '{J20A_CM102A}' or clsID == 'J20_CM102A_DUAL' then
                    cm102 = cm102 + pylonData[i + 1].count
                elseif clsID == 'DIS_GBU_12' then
                    gbu12 = gbu12 + pylonData[i + 1].count
                elseif clsID == 'J_20A_AGM-65E' then
                    agm65 = agm65 + pylonData[i + 1].count
                elseif clsID == "{PLAAF_PL-10E}" or clsID == "{BayArm_PLAAF_PL-10E_x4}" then
                    pl10e = pl10e + pylonData[i + 1].count
                elseif clsID == "{J20A_PL15}" or clsID == "{J20_PL-15_DUAL}" or clsID == "BayArm_J20_PL-15_DUAL" then
                    pl15 = pl15 + pylonData[i + 1].count
				elseif clsID == "{J20A_PL17}" or clsID == "{BayArm_J20_PL-17_x4}" then
                    pl17 = pl17 + pylonData[i + 1].count
                end
                local key = string.format('%.0f%.0f%.0f%.0f', wsType.level1, wsType.level2, wsType.level3, wsType.level4)
                if wsType.level1 == 4 and wsType.level2 == 4 and wsType.level3 == 7 then                    --A2A
                    if type(groupWeaponId[1][key]) == "nil" then
                        groupWeaponId[1][key] = {}
                        groupWeaponId[1][#groupWeaponId[1] + 1] = key
                        groupWeaponId[1].maxType = groupWeaponId[1].maxType + 1
                    end
                    groupWeaponId[1][key][#groupWeaponId[1][key] + 1] = i + 1
                elseif wsType.level1 == 4 and wsType.level2 == 6 and wsType.level3 == 10 then
                    gunPodIdx[#gunPodIdx + 1] = i
                else                    --A2G
                    if type(groupWeaponId[2][key]) == "nil" then
                        groupWeaponId[2][key] = {}
                        groupWeaponId[2][#groupWeaponId[2] + 1] = key
                        groupWeaponId[2].maxType = groupWeaponId[2].maxType + 1
                    end
                    groupWeaponId[2][key][#groupWeaponId[2][key] + 1] = i + 1
                end
            end
        end
    end
    params_h.PL17_COUNT[2] = pl17
	params_h.PL15_COUNT[2] = pl15
    params_h.PL12_COUNT[2] = pl12
    params_h.PL10E_COUNT[2] = pl10e
    params_h.GBU12_COUNT[2] = gbu12
    params_h.LD10_COUNT[2] = ld10
	params_h.CM102_COUNT[2] = cm102
    params_h.AGM65_COUNT[2] = agm65
end

local usingPylon = {}
local usingType = 1
local usingPylonIdx = 0
--刷新应当使用的挂架索引
local function updateUsingPylon()
    local attackMode = params_h.ATK_MODE[2]
    if attackMode > 0 then
        local wpnGroup = groupWeaponId[attackMode]

        -- 激光炮 / 机炮模式优先处理
        if params_h.GUN_MODE[2] == 1 and #gunPodIdx > 0 then
            if params_h.LASER_GUN_CD1[3] == 0 and Weapon_System:get_station_info(8).count > 0 then
                Weapon_System:select_station(8)
                params_h.CURRENT_GUN_IDX[2] = 8
            elseif params_h.LASER_GUN_CD2[3] == 0 and Weapon_System:get_station_info(9).count > 0 then
                Weapon_System:select_station(9)
                params_h.CURRENT_GUN_IDX[2] = 9
            else
                params_h.CURRENT_GUN_IDX[2] = -1
            end
        end

        if wpnGroup.maxType > 0 then
            local groupPylonIdx = wpnGroup[wpnGroup[usingType]]
            local weaponQty = 0
            local candidates = {}

            -- 构建候选列表
            for i = 1, #groupPylonIdx do
                local idx = groupPylonIdx[i]
                local pd  = pylonData[idx]
                local cnt = (pd and pd.count) or 0
                weaponQty = weaponQty + cnt
                candidates[#candidates+1] = {
                    idx = idx,
                    qty = cnt,
                    pos = (idx > 2 and idx < 9) and 1 or 0  -- 外挂=0, 内挂=1
                }
            end

            -- 排序：外挂优先 → 数量多优先 → 编号大优先
            table.sort(candidates, function(a,b)
                if a.pos ~= b.pos then return a.pos < b.pos end
                if a.qty ~= b.qty then return a.qty > b.qty end
                return a.idx > b.idx
            end)

            usingPylonIdx = 0
            for _, c in ipairs(candidates) do
                if c.qty > 0 then
                    usingPylonIdx = c.idx
                    break
                end
            end

            if usingPylonIdx > 0 then
                if params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
                    if usingPylonIdx > 0 and usingPylonIdx < 3 then
                        aircraftArgVal.leftDoor[2]  = Limit(aircraftArgVal.leftDoor[2] + aircraftArgVal.leftDoor[3], 0, 1)
                        aircraftArgVal.rightDoor[2] = Limit(aircraftArgVal.rightDoor[2] + aircraftArgVal.rightDoor[3], 0, 1)
                    else
                        aircraftArgVal.leftDoor[2]  = Limit(aircraftArgVal.leftDoor[2] - aircraftArgVal.leftDoor[3], 0, 1)
                        aircraftArgVal.rightDoor[2] = Limit(aircraftArgVal.rightDoor[2] - aircraftArgVal.rightDoor[3], 0, 1)
                    end
                end
                usingPylon = Weapon_System:get_station_info(usingPylonIdx - 1)
                Weapon_System:select_station(usingPylonIdx - 1)
            else
                usingPylon = nil
            end

            params_h.WEAPON_COUNT[2] = weaponQty
            params_h.PYLON_IDX[2]    = usingPylonIdx
            if usingPylon and usingPylon.CLSID then
                params_h.WEAPON_NAME[2] = weapon_name[usingPylon.CLSID] or ''
                launchAuthorization     = params_h.WEAPON_NAME[2] ~= ''
            else
                params_h.WEAPON_NAME[2] = ''
                launchAuthorization     = false
            end
        end
    elseif params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
        usingPylonIdx = 0
        aircraftArgVal.mainDoor[2]  = Limit(aircraftArgVal.mainDoor[2] - aircraftArgVal.mainDoor[3], 0, 1)
        aircraftArgVal.leftDoor[2]  = Limit(aircraftArgVal.leftDoor[2] - aircraftArgVal.leftDoor[3], 0, 1)
        aircraftArgVal.rightDoor[2] = Limit(aircraftArgVal.rightDoor[2] - aircraftArgVal.rightDoor[3], 0, 1)
    end
end

--[[local function updateUsingPylon()
    local attackMode = params_h.ATK_MODE[2]
    if attackMode > 0 then
        local wpnGroup = groupWeaponId[attackMode]
        if params_h.GUN_MODE[2] == 1 and #gunPodIdx>0 then
            if params_h.LASER_GUN_CD1[3] == 0 and Weapon_System:get_station_info(8).count>0 then
                Weapon_System:select_station(8)
                params_h.CURRENT_GUN_IDX[2] = 8
            elseif params_h.LASER_GUN_CD2[3] == 0 and Weapon_System:get_station_info(8).count>0 then
                Weapon_System:select_station(9)
                params_h.CURRENT_GUN_IDX[2] = 9
            else
                params_h.CURRENT_GUN_IDX[2] = -1
            end
        end
        if wpnGroup.maxType>0 then
            local groupPylonIdx = wpnGroup[ wpnGroup[usingType] ]
            local qty = 0
            local weaponQty = 0
            usingPylonIdx = 0
            for i = 1, #groupPylonIdx, 1 do
                weaponQty = weaponQty + pylonData[ groupPylonIdx[i] ].count
                if pylonData[ groupPylonIdx[i] ].count > qty then
                    qty = pylonData[ groupPylonIdx[i] ].count --计算哪个剩余弹药最多，然后就使用哪个
                    usingPylonIdx = groupPylonIdx[i]
                end
            end
            if usingPylonIdx > 0 then
                if params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
                    if usingPylonIdx > 0 and usingPylonIdx < 3 then
                        aircraftArgVal.leftDoor[2]  = Limit(aircraftArgVal.leftDoor[2] + aircraftArgVal.leftDoor[3], 0, 1)
                        aircraftArgVal.rightDoor[2] = Limit(aircraftArgVal.rightDoor[2] + aircraftArgVal.rightDoor[3], 0, 1)
                    else
                        aircraftArgVal.leftDoor[2]  = Limit(aircraftArgVal.leftDoor[2] - aircraftArgVal.leftDoor[3], 0, 1)
                        aircraftArgVal.rightDoor[2] = Limit(aircraftArgVal.rightDoor[2] - aircraftArgVal.rightDoor[3], 0, 1)
                    end
                end
                usingPylon = Weapon_System:get_station_info(usingPylonIdx - 1)
                Weapon_System:select_station(usingPylonIdx - 1)
            end
            params_h.WEAPON_NAME[2] = weapon_name[usingPylon.CLSID]
            launchAuthorization = params_h.WEAPON_NAME[2] ~= nil
            params_h.WEAPON_COUNT[2] = weaponQty
            params_h.PYLON_IDX[2] = usingPylonIdx
        else

        end
    elseif params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
        usingPylonIdx = 0
        aircraftArgVal.mainDoor[2]=Limit(aircraftArgVal.mainDoor[2]-aircraftArgVal.mainDoor[3],0,1)
        aircraftArgVal.leftDoor[2]=Limit(aircraftArgVal.leftDoor[2]-aircraftArgVal.leftDoor[3],0,1)
        aircraftArgVal.rightDoor[2]=Limit(aircraftArgVal.rightDoor[2]-aircraftArgVal.rightDoor[3],0,1)
    end
end]]

local function updateAircraftArgument()
    for k, v in pairs(aircraftArgVal) do
        set_aircraft_draw_argument_value(v[1],v[2])
    end
end
--------------------------------------------------------------------------------
-- === 导弹 TOF 槽位管理 ===
--------------------------------------------------------------------------------
local MAX_MSL_SLOTS = 6
local mslSlots = {}

local function init_missile_slots()
    for i = 1, MAX_MSL_SLOTS do
        mslSlots[i] = {
            active     = false,
            pylon      = nil,
            tof        = 0,
            remaining  = 0,
            ph_launch  = get_param_handle("HMD_MSL"..i.."_LAUNCHED"),
            ph_tof     = get_param_handle("HMD_MSL"..i.."_TOF"),
            ph_elapsed = get_param_handle("HMD_MSL"..i.."_ELAPSED"),
			ph_remain = get_param_handle("HMD_MSL"..i.."_REMAIN"),
        }
        mslSlots[i].ph_launch:set(0)
        mslSlots[i].ph_tof:set(0)
        mslSlots[i].ph_elapsed:set(0)
		Log_and_print(string.format("MSL_SLOT[%d] initialized", i))
    end
end

local function register_missile_launch(pylonIdx)
    for i, slot in ipairs(mslSlots) do
        if not slot.active then
            slot.active    = true
            slot.pylon     = pylonIdx
            -- 保存发射时挂架剩余弹量
            slot.initCount = (pylonData[pylonIdx] or {}).count or 0

            local cls   = pylonData[pylonIdx].CLSID
            local rng   = target_range_param:get()  -- 米
            Log_and_print(string.format(
                "register_missile_launch: slot=%d, pylon=%d, cls=%s, range=%.1f m",
                i, pylonIdx, cls, rng
            ))

            local host  = { vel = GetGroundSpeed(), alt = sensor_data.getBarometricAltitude() }
            local tgt   = { range = rng, rdot = 0 }
            local tof   = TOFCalc.calculateTOF(cls, host, tgt)

            slot.tof       = tof
            slot.remaining = tof

            slot.ph_launch:set(1)
            slot.ph_tof:set(tof)
            slot.ph_elapsed:set(0)

            Log_and_print(string.format(
                " -> registered, tof=%.2f s, initCount=%d",
                tof, slot.initCount
            ))
            break
        end
    end
end

-- 每帧更新导弹 TOF 槽位（只在剩余时间耗尽或挂架弹量减少时清槽）
local function update_missile_slots(dt)
    for i, slot in ipairs(mslSlots) do
        if slot.active then
            -- 自减倒计时
            slot.remaining = slot.remaining - dt

            -- 当前挂架剩余弹量
            local pcount = (pylonData[slot.pylon] or {}).count or 0

            -- 清槽条件：
            -- 1) 倒计时耗尽
            -- 2) 挂架弹量大于发射前的 initCount（表示重装完成）
            if slot.remaining <= 0 or pcount > slot.initCount then
                slot.active     = false
                slot.ph_launch:set(0)
                slot.ph_tof:set(0)
                slot.ph_elapsed:set(0)
                Log_and_print(string.format(
                    "MSL_SLOT[%d] cleared (rem=%.2f, pcount=%d > init=%d)",
                    i, slot.remaining, pcount, slot.initCount
                ))
            else
                -- 正常更新 elapsed
				slot.ph_remain:set(slot.remaining)
                slot.ph_elapsed:set(slot.tof - slot.remaining)
                Log_and_print(string.format(
                    "update slot[%d]: rem=%.2f, tof=%.2f, pcount=%d",
                    i, slot.remaining, slot.tof, pcount
                ))
            end
        end
    end
end


-----------------------------------------------------------------------------------
--发射逻辑
-----------------------------------------------------------------------------------
local fireHold = 0
local trgDn = false
local isFire = false
-- 发射逻辑
-- 内舱发射后保持开门时间（秒）
local BAY_HOLD_AFTER_SHOT = 1.2
-- 内舱保持开门倒计时
local mainDoor_hold_t = 0
-- 扳机会话：是否处于扳机按下周期
local trg_session_active = false
-- 扳机会话：在按下瞬间选中的是否为内舱且有弹
local trg_session_is_internal = false

-- 发射逻辑
local function launchWpn()
    -- 0. 无效攻击模式直接返回
    if params_h.ATK_MODE[2] <= 0 then
        return
    end

    -- 1. 扳机按压计时
    if trgDn then
        fireHold = fireHold + update_time_step
    else
        fireHold = 0
    end

    -- 1.1 保持时间衰减
    if mainDoor_hold_t > 0 then
        mainDoor_hold_t = math.max(0, mainDoor_hold_t - update_time_step)
    end

    -- 2. 主舱门动画
    if params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
        -- 当前选择是否有“内舱武器存量”
        local cur_internal_has_ammo = false
        if usingPylonIdx > 2 and usingPylonIdx < 9 then
            local st = pylonData[usingPylonIdx]
            cur_internal_has_ammo = st and (st.count or 0) > 0
        end

        -- 预开门条件：
        --   1) 扳机会话锁存是内舱且当前确有内舱弹药
        --   2) 发射后的保持时间
        local open_by_trigger = trg_session_active and trg_session_is_internal and cur_internal_has_ammo
        local open_by_hold = (mainDoor_hold_t > 0)

        local wantOpen = open_by_trigger or open_by_hold
        local delta    = wantOpen and aircraftArgVal.mainDoor[3] or -aircraftArgVal.mainDoor[3]
        aircraftArgVal.mainDoor[2] = Limit(aircraftArgVal.mainDoor[2] + delta, 0, 1)
    end

    -- 3. 没有选中挂架就不再执行发射部分
    if not usingPylon or not usingPylon.CLSID then
        return
    end

    local lvl1 = usingPylon.weapon.level1
    local lvl2 = usingPylon.weapon.level2
    local lvl3 = usingPylon.weapon.level3

    -- 空空导弹
    if lvl1 == 4 and lvl2 == 4 then
        if fireHold > 1 and not isFire and launchAuthorization then
            register_missile_launch(usingPylonIdx)
            Weapon_System:launch_station(usingPylonIdx - 1)
            isFire = true
            -- 发射成功：若为内舱，刷新保持时间
            if (usingPylonIdx > 2 and usingPylonIdx < 9) and params_h.WPN_ROOM_STATUS[2] == 0 then
                mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
            end
        end
        return
    end

    -- 火箭 / 炸弹
    if (lvl1 == 4 and lvl2 == 7 and lvl3 == 33) or (lvl1 == 4 and lvl2 == 5) then
        local threshold = ccrp_status and 0 or 0.25
        local readyToLaunch =
            (ccrp_status and params_h.CCRP_TIME[2] <= 0.05 and fireHold > 0) or
            (not ccrp_status and fireHold > threshold)

        if readyToLaunch and launchAuthorization then
            if usingPylon.CLSID == 'DIS_GBU_12' then
                if not isFire then
                    Weapon_System:launch_station(usingPylonIdx - 1)
                    isFire = true
                    if (usingPylonIdx > 2 and usingPylonIdx < 9) and params_h.WPN_ROOM_STATUS[2] == 0 then
                        mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
                    end
                end
            else
                Weapon_System:launch_station(usingPylonIdx - 1)
                if (usingPylonIdx > 2 and usingPylonIdx < 9) and params_h.WPN_ROOM_STATUS[2] == 0 then
                    mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
                end
            end
        end
    end
end
--[[local function launchWpn()
    -- 0. 无效攻击模式直接返回
    if params_h.ATK_MODE[2] <= 0 then
        return
    end

    -- 1. 扳机按压计时
    if trgDn then
        fireHold = fireHold + update_time_step
    else
        fireHold = 0
    end

    -- 1.1 保持时间衰减
    if mainDoor_hold_t > 0 then
        mainDoor_hold_t = math.max(0, mainDoor_hold_t - update_time_step)
    end

    -- 2. 主舱门动画（与 usingPylon 是否有效无关）
    if params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
        local isInternal = (usingPylonIdx > 2 and usingPylonIdx < 9)
        local wantOpen   = isInternal and (fireHold > 0 or mainDoor_hold_t > 0)
        local delta      = wantOpen and aircraftArgVal.mainDoor[3] or -aircraftArgVal.mainDoor[3]
        aircraftArgVal.mainDoor[2] = Limit(aircraftArgVal.mainDoor[2] + delta, 0, 1)
    end

    -- 3. 没有选中挂架就不再执行发射部分
    if not usingPylon or not usingPylon.CLSID then
        return
    end

    local lvl1 = usingPylon.weapon.level1
    local lvl2 = usingPylon.weapon.level2
    local lvl3 = usingPylon.weapon.level3

    -- 空空导弹
    if lvl1 == 4 and lvl2 == 4 then
        if fireHold > 1 and not isFire and launchAuthorization then
            register_missile_launch(usingPylonIdx)
            Weapon_System:launch_station(usingPylonIdx - 1)
            isFire = true
            if params_h.WPN_ROOM_STATUS[2] == 0 and (usingPylonIdx > 2 and usingPylonIdx < 9) then
                mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
            end
        end
        return
    end

    -- 火箭 / 炸弹
    if (lvl1 == 4 and lvl2 == 7 and lvl3 == 33) or (lvl1 == 4 and lvl2 == 5) then
        local threshold = ccrp_status and 0 or 0.25
        local readyToLaunch =
            (ccrp_status and params_h.CCRP_TIME[2] <= 0.05 and fireHold > 0) or
            (not ccrp_status and fireHold > threshold)
        if readyToLaunch and launchAuthorization then
            if usingPylon.CLSID == 'DIS_GBU_12' then
                if not isFire then
                    Weapon_System:launch_station(usingPylonIdx - 1)
                    isFire = true
                    if params_h.WPN_ROOM_STATUS[2] == 0 and (usingPylonIdx > 2 and usingPylonIdx < 9) then
                        mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
                    end
                end
            else
                Weapon_System:launch_station(usingPylonIdx - 1)
                if params_h.WPN_ROOM_STATUS[2] == 0 and (usingPylonIdx > 2 and usingPylonIdx < 9) then
                    mainDoor_hold_t = BAY_HOLD_AFTER_SHOT
                end
            end
        end
    end
end]]
--[[local function launchWpn()
    -- 0. 只有在有效攻击模式下才执行
    if params_h.ATK_MODE[2] <= 0 then
        return
    end

    -- 1. 累积触发器按住时长
    if trgDn then
        fireHold = fireHold + update_time_step
    else
        fireHold = 0
    end

    -- 2. 确保已有有效挂架
    if not usingPylon or not usingPylon.CLSID then
        return
    end

    -- 3. 弹仓/弹舱动画（同空空与炸弹共用）
    if params_h.WPN_ROOM_STATUS[2] == 0 and not weaponLoading then
        local open   = usingPylonIdx > 2 and usingPylonIdx < 9 and fireHold > 0
        local delta  = open and aircraftArgVal.mainDoor[3] or -aircraftArgVal.mainDoor[3]
        aircraftArgVal.mainDoor[2] = Limit(aircraftArgVal.mainDoor[2] + delta, 0, 1)
    end

    -- 解包武器等级
    local lvl1 = usingPylon.weapon.level1
    local lvl2 = usingPylon.weapon.level2
    local lvl3 = usingPylon.weapon.level3

    ------------- 空空导弹分支 -------------
    if lvl1 == 4 and lvl2 == 4 then
        -- 长按超过1秒，且未发射过，且有发射许可
        if fireHold > 1 and not isFire and launchAuthorization then
            -- 注册 TOF 槽位
            register_missile_launch(usingPylonIdx)
            -- 真正发射导弹
            Weapon_System:launch_station(usingPylonIdx - 1)
            Log_and_print("Missile launched from pylon "..usingPylonIdx)
            -- 标记已发射，防止重复
            isFire = true
        end
        return
    end

    ------------- 火箭/炸弹分支 -------------
    if (lvl1 == 4 and lvl2 == 7 and lvl3 == 33) or (lvl1 == 4 and lvl2 == 5) then
        -- 根据 CCRP 状态选择不同的触发阈值
        local threshold = ccrp_status and 0 or 0.25
        -- CCRP 模式下，还要等 CCRP_TIME<=0.05
        local readyToLaunch =
            (ccrp_status and params_h.CCRP_TIME[2] <= 0.05 and fireHold > 0) or
            (not ccrp_status and fireHold > threshold)
        if readyToLaunch and launchAuthorization then
            if usingPylon.CLSID == 'DIS_GBU_12' then
                -- GBU-12 要防抖，多发只触发一次
                if not isFire then
                    Weapon_System:launch_station(usingPylonIdx - 1)
                    isFire = true
                end
            else
                Weapon_System:launch_station(usingPylonIdx - 1)
            end
        end
    end
end]]

-----------------------------------------------------------------------------------
local function updateAntiMslInfo()
    params_h.CHAFF_QTY[2] = Weapon_System:get_chaff_count()
    params_h.FLARE_QTY[2] = Weapon_System:get_flare_count()
end

local function updateWPNPageInfo()
    --更新选择与未选择
    if params_h.ATK_MODE[2]>0 then
        local attackMode = params_h.ATK_MODE[2]
        local wpnGroup = groupWeaponId[attackMode]
        local groupPylonIdx = wpnGroup[wpnGroup[usingType]]--当前所选择的武器种类可用的挂架索引集(挂架索引从1开始)
        for k, v in pairs(pylonData) do
            local key = string.format('MSL_%.0f_SELECTED',k)
            local idx = GetIndexOfValInTbl(groupPylonIdx,k)
            if type(idx)~="nil" then
                params_h[key][2] = 1
            else
                params_h[key][2] = 0
            end
        end
    else
        for i = 1, 8, 1 do
            local k = string.format('MSL_%.0f_SELECTED',i)
            params_h[k][2]=0
        end
    end
    --更新武器是否存在以及武器种类以及是否正在使用
    for k, v in pairs(pylonData) do
		-- 1. 挂架子弹数量 & 是否在用
        local key = string.format('MSL_%.0f_COUNT',k)
        params_h[key][2] = v.count
        key = string.format('MSL_%.0f_USING',k)
		params_h[key][2] = (k == usingPylonIdx) and 1 or 0

		-- 2. 构建所有武器对应的参数名
        local pl12Key	= string.format('MSL_%.0f_PL12',	k)
        local ld10Key	= string.format('MSL_%.0f_LD10',	k)
        local pl15Key	= string.format('MSL_%.0f_PL15',	k)
		local pl17Key	= string.format('MSL_%.0f_PL17',	k)
        local pl10eKey	= string.format('MSL_%.0f_PL10E',	k)
        local bombKey	= string.format('MSL_%.0f_BOMB',	k)
        local agm65eKey = string.format('MSL_%.0f_AGM65E',	k)
        local yj83Key	= string.format('MSL_%.0f_YJ83',	k)
        local yj12Key	= string.format('MSL_%.0f_YJ12',	k)
        local gunKey	= string.format('MSL_%.0f_GUNPOD',	k)
		local cm102Key  = string.format('MSL_%.0f_CM102',	k)

		-- 3. 默认全部清零
		params_h[pl12Key][2]   = 0
		params_h[ld10Key][2]   = 0
		params_h[pl15Key][2]   = 0
		params_h[pl17Key][2]   = 0
		params_h[pl10eKey][2]  = 0
		params_h[bombKey][2]   = 0
		params_h[agm65eKey][2] = 0
		params_h[yj83Key][2]   = 0
		params_h[yj12Key][2]   = 0
		params_h[gunKey][2]    = 0
		params_h[cm102Key][2]  = 0

        if v.CLSID == "DIS_PL-12" then
			params_h[pl12Key][2] = 1
        elseif (v.CLSID == "{J20A_PL15}" or v.CLSID == 'J20_PL-15_DUAL' or v.CLSID == 'BayArm_J20_PL-15_DUAL') then
            params_h[pl15Key][2] = 1
		elseif (v.CLSID == "{J20A_PL17}" or v.CLSID == "{BayArm_J20_PL-17_x4}") then
			params_h[pl17Key][2] = 1
        elseif (v.CLSID == "{PLAAF_PL-10E}" or v.CLSID == "{BayArm_PLAAF_PL-10E_x4}") then
			params_h[pl10eKey][2] = 1
        elseif v.CLSID == "DIS_LD-10" or v.CLSID == "DIS_LD-10_DUAL_L" then
            params_h[ld10Key][2] = 1
        elseif v.CLSID == "J_20A_AGM-65E" then
            params_h[agm65eKey][2] = 1
        elseif v.CLSID == 'DIS_DF4B_YJ12' then
            params_h[yj12Key][2] = 1
        elseif v.CLSID == 'DIS_GDJ_YJ83K' then
            params_h[yj83Key][2] = 1
        elseif v.CLSID == 'J20C_Laser_Cannon_POD' or v.CLSID == 'J20C_EML_POD' then
            params_h[gunKey][2] = 1
        elseif v.weapon.level1 == 4 and v.weapon.level2 == 5 then            --炸弹
            params_h[bombKey][2] = 1
		elseif v.CLSID == "{J20A_CM102A}" or v.CLSID == "J20_CM102A_DUAL" then
			params_h[cm102Key][2] = 1
        end
    end
end

local function updateIrMissileSeek()
    ir_seek_az=ir_seek_az+1
    if ir_seek_az > ir_seek_az_limit[2] then
        ir_seek_el = ir_seek_el + 1
        ir_seek_az = ir_seek_az_limit[1]
        if ir_seek_el > ir_seek_el_limit[2] then
            ir_seek_el = ir_seek_el_limit[1]
        end
    end
end

local hud_dis 			= get_param_handle('HUD_BRT')
local radarMode 		= get_param_handle('RADAR_MODE')
local stt_azimuth_h 	= get_param_handle("RADAR_STT_AZIMUTH")
local stt_elevation_h 	= get_param_handle("RADAR_STT_ELEVATION")
local stt_range_h 		= get_param_handle("RADAR_STT_RANGE")

local function update_ir_msl_status()
    if math.abs(head_az:get())>30 or math.abs(head_el:get())>30 then
        params_h.IR_SEEK_LIMIT[2] = 1
    else
        params_h.IR_SEEK_LIMIT[2] = 0
    end
    if ((usingPylonIdx == 1 or usingPylonIdx == 2) and (pylonData[usingPylonIdx].CLSID == '{PLAAF_PL-10E}' or pylonData[usingPylonIdx].CLSID == '{BayArm_PLAAF_PL-10E_x4}')) then
        if ir_selected == 0 then
            dispatch_action(devices.RADAR_RAW,Keys.setRadarStable,0)
            ir_selected = 1
        end
        params_h.IR_SEEK_RANGE_DIS[2] = 1
        if pylonData[usingPylonIdx].count > 0 then
            if ir_missile_lock_param:get() == 1 then
                params_h.IR_SEEK_RANGE_DIS[2] = 0
                params_h.TARGET_ROUND_DIS_ENABLE[2] = hud_dis:get()
                if snd_list.sidewinder_quiet:is_playing() then
                    snd_list.sidewinder_quiet:stop()
                end
                if snd_list.sidewinder_low:is_playing() then
                    snd_list.sidewinder_low:stop()
                end
                local temp_ir_az = ir_missile_az_param:get()
                local temp_ir_el = ir_missile_el_param:get()
                params_h.TARGET_ROUND_X[2] = math.tan(temp_ir_az) * HUD_distance
                params_h.TARGET_ROUND_Y[2] = math.tan(temp_ir_el) * HUD_distance
                --HMD
                params_h.HMD_TARGET_ROUND_X[2] = math.tan(temp_ir_az-math.rad(-head_az:get()))
                params_h.HMD_TARGET_ROUND_Y[2] = math.tan(temp_ir_el-math.rad(head_el:get()))
                ir_missile_des_az_param:set(temp_ir_az)
                ir_missile_des_el_param:set(temp_ir_el)
                if not snd_list.sidewinder_high:is_playing() then
                    snd_list.sidewinder_high:play_continue()
                end
            else
                ir_seek_step_time = ir_seek_step_time + update_time_step
                if ir_seek_step_time> ir_seek_scan_speed and radarMode:get() ~= 3 then
                    updateIrMissileSeek()
                    ir_seek_step_time = 0
                end
                params_h.TARGET_ROUND_DIS_ENABLE[2] = 1
                params_h.HMD_TARGET_ROUND_DIS_ENABLE[2] = 1
                params_h.TARGET_ROUND_X[2] = 0
                params_h.TARGET_ROUND_Y[2] = 0
				params_h.HMD_TARGET_ROUND_X[2] = 0
                params_h.HMD_TARGET_ROUND_Y[2] = 0
                if radarMode:get() == 3 then
                    ir_seek_az=math.deg(stt_azimuth_h:get())
                    ir_seek_el=math.deg(stt_elevation_h:get())
                    ir_seek_el_offset = 0
                    ir_seek_az_offset = 0
                elseif hmdType_h:get() == 0 and (math.abs(head_az:get())>7 or math.abs(head_el:get())>7) then
                    --头盔瞄准
                    ir_seek_el_offset = math.rad(head_el:get())
                    ir_seek_az_offset = math.rad(head_az:get())
                else
                    ir_seek_el_offset = 0
                    ir_seek_az_offset = 0
                end
                ir_missile_des_el_param:set(ir_seek_el_offset+math.rad(ir_seek_el))
                ir_missile_des_az_param:set(ir_seek_az_offset+math.rad(ir_seek_az))
                if snd_list.sidewinder_high:is_playing() then
                    snd_list.sidewinder_high:stop()
                end
                if not snd_list.sidewinder_low:is_playing() then
                    snd_list.sidewinder_low:play_continue()
                end
            end
        else
            if snd_list.sidewinder_high:is_playing() then
                snd_list.sidewinder_high:stop()
            end
            if snd_list.sidewinder_quiet:is_playing() then
                snd_list.sidewinder_quiet:stop()
            end
            if snd_list.sidewinder_low:is_playing() then
                snd_list.sidewinder_low:stop()
            end
            ir_missile_des_az_param:set(0)
            ir_missile_des_el_param:set(0)
            params_h.TARGET_ROUND_DIS_ENABLE[2] = 0
            params_h.HMD_TARGET_ROUND_DIS_ENABLE[2] = 0
            params_h.TARGET_ROUND_X[2] = 0
            params_h.TARGET_ROUND_Y[2] = 0
			params_h.HMD_TARGET_ROUND_X[2] = 0
            params_h.HMD_TARGET_ROUND_Y[2] = 0
        end
    else
        if ir_selected == 1 then
            dispatch_action(devices.RADAR_RAW,Keys.setRadarStable,1)
            ir_selected = 0
        end
        params_h.IR_SEEK_RANGE_DIS[2] = 0
        if snd_list.sidewinder_high:is_playing() then
            snd_list.sidewinder_high:stop()
        end
        if snd_list.sidewinder_quiet:is_playing() then
            snd_list.sidewinder_quiet:stop()
        end
        if snd_list.sidewinder_low:is_playing() then
            snd_list.sidewinder_low:stop()
        end
        ir_missile_des_az_param:set(0)
        ir_missile_des_el_param:set(0)
        params_h.TARGET_ROUND_DIS_ENABLE[2] = 0
        params_h.TARGET_ROUND_X[2] = 0
        params_h.TARGET_ROUND_Y[2] = 0
		params_h.HMD_TARGET_ROUND_DIS_ENABLE[2] = 0
        params_h.HMD_TARGET_ROUND_X[2] = 0
        params_h.HMD_TARGET_ROUND_Y[2] = 0
    end
end

local Ralt_last = 1600
local Balt_last = 1600

local function updateCCIP()
    if usingPylon==nil or usingPylonIdx<=0 or params_h.CCRP_DIS_ENABLE[2]==1 then
        params_h.CCIP_DIS_ENABLE[2] = 0
        params_h.CCIP_Y[2] = 0
        params_h.CCIP_X[2] = 0
        do return end
    end
    local x, y, z = sensor_data.getSelfCoordinates()
    local Vx0, Vy0, Vz0 = sensor_data.getSelfVelocity()
    local p_roll = BASE_SENSOR.ROLL:get()
    local p_pitch = BASE_SENSOR.PITCH:get()
    local Ralt = BASE_SENSOR.RADALT:get()
    local Balt = BASE_SENSOR.BAROALT:get()
    if Ralt < 1600 then
        Ralt_last = Ralt
        Balt_last = Balt
    end
    local h0 = y - (Ralt_last + Balt - Balt_last) * math.cos(math.abs(p_pitch)) * math.cos(math.abs(p_roll))
    local valid, az, el, travel_dist = 0,0,0,0
    if USE_EXT_DLL and Type then
    	set_target_level(h0)
		valid, az, el, travel_dist = Calculate()
	elseif type(avSimplestWeaponSystem)~='nil' then
        avSimplestWeaponSystem.set_target_level(h0)
        valid, az, el, travel_dist = avSimplestWeaponSystem.Calculate()
	end
    if usingPylon.weapon.level1 == 4 and usingPylon.weapon.level2 == 5 then
        params_h.CCIP_DIS_ENABLE[2] = 1
        params_h.CCIP_Y[2] = math.tan(el)*HUD_distance
        params_h.CCIP_X[2] = math.tan(az)*HUD_distance
    else
        params_h.CCIP_DIS_ENABLE[2] = 0
        params_h.CCIP_Y[2] = 0
        params_h.CCIP_X[2] = 0
    end
end
--from A-29B
local function calculate_ccip_max_range(h0)
    local fly_time, Vx0, Vy0, Vz0, g
    local pitch = sensor_data.getPitch()
    g = -9.82 -- m/s2

    Vx0, Vy0, Vz0 = sensor_data.getSelfVelocity()
    local vel_temp = math.sqrt(Vx0^2 + Vy0^2 + Vz0^2)
    Vy0 = vel_temp / math.sqrt(2)

    local delta = Vy0^2 - 2 * g * (math.abs(h0))
    fly_time = (-Vy0  - math.sqrt(delta))/g                -- time to impact

    local Vx = Vy0                                  -- horizontal weapon velocity
    local Sx = Vx * fly_time                               -- horizontal distance travelled by weapon
    return Sx, fly_time, h0
end

local flir_tgt = {
    LAT = get_param_handle('FLIR_TGT_LAT'),
    LON = get_param_handle('FLIR_TGT_LON'),
    ALT = get_param_handle('FLIR_TGT_ALT'),
    Mode = get_param_handle('FLIR_MODE'),
}

local function update_ccrp()
    local atk_idx = atk_wpt_h:get()
    if params_h.ATK_MODE[2]==2 and (usingPylonIdx==5 or usingPylonIdx==6) and pylonData[usingPylonIdx]~=nil and GetTableLength(pylonData[usingPylonIdx])>0 then
        if #ATK_WPT_data<1 or atk_idx < 1 then
            if flir_tgt.Mode:get()~=3 then
                --无效攻击点
                params_h.CCRP_TIME[2]=-1
                params_h.CCRP_DIS_ENABLE[2]=0
                ccrp_status = false
                do return end
            end
        end
        local maxRange = maxRange_h:get()
        local x, y, z = sensor_data.getSelfCoordinates()
        local dx
        local dy
        local dz
        if flir_tgt.Mode:get()==3 then
            dx = flir_tgt.LAT:get() - x
            dy = flir_tgt.ALT:get() - y
            dz = flir_tgt.LON:get() - z
        else
            dx = ATK_WPT_data[atk_idx].LAT:get()*(maxRange/40) - x
            dy = ATK_WPT_data[atk_idx].ALT:get() - y
            dz = ATK_WPT_data[atk_idx].LON:get()*(maxRange/40) - z
        end

        local max_range = calculate_ccip_max_range(dy)

        local valid, az, el, travel_dist = 0, 0, 0, 0
        if USE_EXT_DLL and Type then
        	valid, az, el, travel_dist = Calculate()
		elseif type(avSimplestWeaponSystem) ~= 'nil' then
            valid, az, el, travel_dist = avSimplestWeaponSystem.Calculate()
		end
        local vx, vy, vz = sensor_data.getSelfVelocity()
        local gs = math.sqrt(vx*vx + vz*vz)
        local fly_time=travel_dist/gs

        local target_dist = math.sqrt(dx * dx + dy * dy +  dz * dz)
        local target_horiz_dist = math.sqrt(dx * dx +  dz * dz)

        local ccrp_dif = target_dist - travel_dist
        local ccrp_time = 0
        if ccrp_dif >= 0 then
            ccrp_time = ccrp_dif / gs
        end
        local ccrp_az = math.atan2(dz,dx)
        if ccrp_az<0 then
			ccrp_az=ccrp_az+math.rad(360)
		end
        ccrp_az = Limit(ccrp_az - math.rad(t_hdg_h:get()),-HUD_AZ,HUD_AZ)
        local time_to_max_range = (target_horiz_dist - max_range) / gs
        params_h.CCRP_TIME[2]=ccrp_time
        params_h.CCRP_TIME_MAX_RANGE[2]=time_to_max_range
        params_h.CCRP_TIME_TO_IMPACT[2]=fly_time
        params_h.CCRP_X[2]=math.tan(ccrp_az)*HUD_distance
        params_h.CCRP_Y[2]=math.tan(el)*HUD_distance
        params_h.CCRP_DIS_ENABLE[2]=1
        ccrp_status = true
    else
        params_h.CCRP_TIME[2]=-1
        params_h.CCRP_DIS_ENABLE[2]=0
        ccrp_status = false
    end
end

local function updateATK_wpts()
    ATK_WPT_data = {}
    for i = 1, 100, 1 do
        if WPT_data[i].TYPE:get()==2 then
            ATK_WPT_data[#ATK_WPT_data+1] = WPT_data[i]
        end
    end
    params_h.ATK_WPT_MAX[2] = #ATK_WPT_data
end

local function smokeOnOff(i)
    local station = Weapon_System:get_station_info(i)
    if station~=nil then
        Weapon_System:select_station(i)
        Weapon_System:launch_station(i)
    end
end

local function updateGunFire()
    if params_h.GUN_MODE[2] == 1 and gunFire == 1 then
        if params_h.GUN_TYPE[2] == 1 then
            if params_h.LASER_GUN_CHARGE[3] > 2 and not isFire and launchAuthorization then
                --蓄力完成，可以发射
                if params_h.LASER_GUN_CD1[3] == 0 and params_h.CURRENT_GUN_IDX[2] >= 0 then
                    Weapon_System:launch_station(params_h.CURRENT_GUN_IDX[2])
                    dispatch_action(nil,SND_cmd.LaserFire,1)
                    params_h.LASER_GUN_CD1[3] = 10--左激光炮进入冷却CD
                elseif params_h.LASER_GUN_CD1[3] > 0 and params_h.LASER_GUN_CD2[3] == 0 and params_h.CURRENT_GUN_IDX[2] >= 0 then
                    Weapon_System:launch_station(params_h.CURRENT_GUN_IDX[2])
                    dispatch_action(nil,SND_cmd.LaserFire,1)
                    params_h.LASER_GUN_CD2[3] = 10--右激光炮进入冷却CD
                end
                isFire = true
                params_h.LASER_GUN_CHARGE[2] = 0
                params_h.LASER_GUN_CHARGE[3] = 0
            elseif not isFire then
                if params_h.LASER_GUN_CHARGE[2] == 0 and (params_h.LASER_GUN_CD1[3] == 0 or params_h.LASER_GUN_CD2[3] == 0) then
                    params_h.LASER_GUN_CHARGE[2] = 2.1
                end
            end
        elseif params_h.GUN_TYPE[2] == 0 then
            gunFireTime= gunFireTime + update_time_step
            if gunFireTime < 12.96 then
                params_h.GUN_COUNT[2] = Limit(params_h.GUN_COUNT[2] - 1,0,648)
            end
            if params_h.GUN_COUNT[2] == 0 and unlimited_weapons then
                params_h.GUN_COUNT[2] = 648
            end
        end
    else
        gunFire = 0
        gunFireTime = 0
    end
    if #gunPodIdx>0 then
        local gunStation = Weapon_System:get_station_info(8)
        if gunStation then
            if gunStation.CLSID == 'J20C_Laser_Cannon_POD' then
                params_h.LaserCannonAmmo_L[2] = math.floor(gunStation.count/600)
            else
                params_h.LaserCannonAmmo_L[2] = gunStation.count
            end
        else
            params_h.LaserCannonAmmo_L[2] = 0
        end
        gunStation = Weapon_System:get_station_info(9)
        if gunStation then
            if gunStation.CLSID == 'J20C_Laser_Cannon_POD' then
                params_h.LaserCannonAmmo_R[2] = math.floor(gunStation.count/600)
            else
                params_h.LaserCannonAmmo_R[2] = gunStation.count
            end
        else
            params_h.LaserCannonAmmo_R[2] = 0
        end
    end
end

local function updateTarget()
    if radarMode:get()==3 then
        Weapon_System:set_target_range(stt_range_h:get())
    else
        Weapon_System:set_target_range(1000)
    end
end

local function update_cannon_track()
    if params_h.GUN_MODE[2] == 1 and params_h.GUN_TYPE[2] == 0 then
        params_h.GUN_CCIP_DIS_ENABLE[2] = 1
        params_h.GUN_CCIP_X[2] = math.tan(gun_piper_az_param:get())*HUD_distance
        params_h.GUN_CCIP_Y[2] = math.tan(gun_piper_el_param:get())*HUD_distance
    else
        params_h.GUN_CCIP_DIS_ENABLE[2] = 0
        params_h.GUN_CCIP_X[2] = 0
        params_h.GUN_CCIP_Y[2] = 0
    end
    if params_h.GUN_TYPE[2] == 0 then
        params_h.GUN_NAME[2] = 'GSH-23-2'
    else
        if Weapon_System:get_station_info(gunPodIdx[1]).CLSID == 'J20C_Laser_Cannon_POD' then
            params_h.GUN_NAME[2] = 'Laser Pod'
        elseif Weapon_System:get_station_info(gunPodIdx[1]).CLSID == 'J20C_EML_POD' then
            params_h.GUN_NAME[2] = 'EML Pod'
        end
    end
end

local function emergJettion(stationIdx)
    local station = Weapon_System:get_station_info(stationIdx)
    if station then
        Weapon_System:emergency_jettison(stationIdx)
        if not station.container then
            if stationIdx == 8 then
                set_aircraft_draw_argument_value(210,0)
            elseif stationIdx == 9 then
                set_aircraft_draw_argument_value(211,0)
            elseif stationIdx == 10 then
                set_aircraft_draw_argument_value(212,0)
            elseif stationIdx == 11 then
                set_aircraft_draw_argument_value(213,0)
            end
        end
    end
end

-- 每帧计算动态 DLZ（基于高度、地速、相对速度）
local function updateDLZ_Dynamic()
    if usingPylonIdx > 0 then
        local info = Weapon_System:get_station_info(usingPylonIdx-1)
	--	Log_and_print("PylonIdx="..usingPylonIdx.." CLSID="..tostring(info and info.CLSID), 0.1)

        if info and info.CLSID then
			-- DEBUG1: 打印实际拿到的 CLSID
        --    Log_and_print("DEBUG CLSID = "..tostring(info.CLSID), 1)

            -- 本机地速 m/s
            local gs = GetGroundSpeed()
            -- 简化：无径向目标速度
            local targVel = 0
            -- 本机海拔 m
            local alt = sensor_data.getBarometricAltitude() or 0
			--Log_and_print(string.format("gs=%.1f alt=%.0f", gs, alt), 0.1)

            -- 调用 新版 DLZCalculator
            -- 增加 margin_km（最佳点的拦截余量）
            local min_km, best_km, max_km, margin_km = DLZCalc.calculateDLZ(info.CLSID, gs, targVel, alt)
			-- DEBUG2: 显示计算结果
        --    Log_and_print(string.format("DLZcalc(%s): %.2f/%.2f/%.2f", info.CLSID, min_km, best_km, max_km),1)
			local min_nm, best_nm, max_nm = min_km*KM_TO_NM,best_km*KM_TO_NM,max_km*KM_TO_NM

            if max_km > 0 then
                dlz_min_dyn:set(min_km)
                dlz_best_dyn:set(best_km)
                dlz_max_dyn:set(max_km)
				dlz_margin_dyn:set(margin_km)
				dlz_min_dyn_NM:set(min_nm)
                dlz_best_dyn_NM:set(best_nm)
                dlz_max_dyn_NM:set(max_nm)
				dlz_margin_dyn_NM:set(margin_km * KM_TO_NM)
                dlz_auth_dyn:set(1)
                return
            end
        end
    end
    -- 无效时清零
    dlz_min_dyn:set(0)
    dlz_max_dyn:set(0)
	dlz_best_dyn:set(0)
	dlz_margin_dyn:set(0)
    dlz_auth_dyn:set(0)
end
--------------------------------------------------------------------------------
-- post_initialize
----------------------------------------------------------------------------
function post_initialize()
	if not USE_EXT_DLL and Type and type(avSimplestWeaponSystem)~='nil' then
        avSimplestWeaponSystem.Setup()
	--	Log_and_print("avSimplestWeaponSystem Setup")
	end
    initSnd()
    initWPTs()
	init_missile_slots()
    unlimited_weapons = LockOn_Options.flight.unlimited_weapons
end

function SetCommand(command, value)
	--DebugPrint('武器系统：'..Get_command_name(command)..' value='..value)
    -- 切换武器类型：跳过剩弹为零的挂架
    if command == Keys.WeaponSelectNext then
        if params_h.GUN_MODE[2] == 1 and #gunPodIdx > 0 then
            -- 机炮模式：切换激光/铁炮
            params_h.GUN_TYPE[2] = 1 - params_h.GUN_TYPE[2]
        elseif params_h.ATK_MODE[2] > 0 then
            -- A/A 或 A/G 模式下切换导弹/挂载类型
            local attackMode = params_h.ATK_MODE[2]
            local groupInfo  = groupWeaponId[attackMode]
            local maxType    = groupInfo.maxType
            local nextType   = usingType
            for i = 1, maxType do
                nextType = nextType + 1
                if nextType > maxType then nextType = 1 end
                local pylons = groupInfo[groupInfo[nextType]]
                local total  = 0
                for _, idx in ipairs(pylons) do
                    total = total + (pylonData[idx].count or 0)
                end
                if total > 0 then
                    usingType = nextType
                    break
                end
            end
        end

    -- 发射键按下/松开
    elseif command == Keys.WeaponLaunch and master_Arm == 1 then
        if params_h.GUN_MODE[2] == 1 then
            -- 机炮模式
            gunFire = value
            if params_h.GUN_TYPE[2] == 0 then
                dispatch_action(nil, Keys.PlaneFire, 1)
            end
        else
            -- 导弹 / 炸弹模式
            if value == 1 then
                trgDn = true
                -- 扳机会话开始：按下这一刻锁存是否为内舱且有弹
                trg_session_active = true
                local isInternalNow = (usingPylonIdx > 2 and usingPylonIdx < 9)
                local hasAmmoNow = false
                if usingPylonIdx > 0 then
                    local st = pylonData[usingPylonIdx]
                    hasAmmoNow = st and (st.count or 0) > 0
                end
                trg_session_is_internal = (isInternalNow and hasAmmoNow) and true or false
            end
        end

        if value == 0 then
            trgDn = false
            dispatch_action(nil, Keys.PlaneFireOff, 1)
            isFire = false
            -- 扳机会话结束
            trg_session_active = false
            trg_session_is_internal = false
        end

        --[[if params_h.GUN_MODE[2] == 1 then
            -- 机炮模式
            gunFire = value
            if params_h.GUN_TYPE[2] == 0 then
                dispatch_action(nil, Keys.PlaneFire, 1)
            end
        else
            -- 导弹模式：value==1 开始计时，value==0 松开则重置 isFire
            if value == 1 then
                trgDn = true
            end
        end
		if value == 0 then
               trgDn     = false
               dispatch_action(nil, Keys.PlaneFireOff, 1)
			isFire    = false           -- 允许下一次发射                
        end]]
    -- 掉落欺骗弹
    elseif command == Keys.DropChaff then
        Weapon_System:drop_chaff()
    elseif command == Keys.DropFlare then
        Weapon_System:drop_flare()
    elseif command == Keys.DropChaffAndFlare then
        Weapon_System:drop_flare()
        Weapon_System:drop_chaff()

    -- 主武器主/安全档切换
    elseif command == Keys.masterArm then
        master_Arm = 1 - master_Arm
        Weapon_System:performClickableAction(click_cmd.masterArm, 1 - master_Arm)
    elseif command == Keys.PlaneAHCPMasterArm then
        Weapon_System:performClickableAction(click_cmd.masterArm, 1)
        master_Arm = 1
    elseif command == Keys.PlaneAHCPMasterSafe then
        Weapon_System:performClickableAction(click_cmd.masterArm, 0)
        master_Arm = 0
	elseif command == click_cmd.masterArm then
        master_Arm = value
    -- MFD 上 A/A、A/G 模式切换
    elseif command == MFD_click_cmd.WPN_AAMODE then
        if params_h.ATK_MODE[2] == 1 then
            params_h.ATK_MODE[2] = 0
            params_h.GUN_MODE[2] = 0
            params_h.GUN_TYPE[2] = 0
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 1)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 0)
            dispatch_action(devices.MFCD,       Keys.P2_to_fcsPage)
        else
            params_h.ATK_MODE[2] = 1
            usingType = 1
            dispatch_action(devices.MFCD,       Keys.P2_to_radarPage)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 1)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 0)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN6,   1)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN6,   0)
        end
        dispatch_action(devices.RADAR_RAW, Keys.STICK_SENSOR_CONTROL_RIGHT, 1)

    elseif command == MFD_click_cmd.WPN_AGMODE then
        if params_h.ATK_MODE[2] == 2 then
            params_h.ATK_MODE[2] = 0
            params_h.GUN_MODE[2] = 0
            params_h.GUN_TYPE[2] = 0
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 1)
            dispatch_action(devices.MFCD_BACKUP, MFCD_click_cmd.BTN23, 0)
            dispatch_action(devices.MFCD,       Keys.P2_to_fcsPage)
        else
            params_h.ATK_MODE[2] = 2
            usingType = 1
            dispatch_action(devices.MFCD,       Keys.P2_to_flirPage)
        end

    -- 弹仓门控制
    elseif command == MFD_click_cmd.WPN_DOOR_ON then
        params_h.WPN_ROOM_STATUS[2] = 1
    elseif command == MFD_click_cmd.WPN_DOOR_AUTO then
        params_h.WPN_ROOM_STATUS[2] = 0

	-- 快捷键：A2A / A2G
    elseif command == Keys.A2A then
        Weapon_System:performClickableAction(MFD_click_cmd.WPN_AAMODE, 1)

    elseif command == Keys.A2G then
        Weapon_System:performClickableAction(MFD_click_cmd.WPN_AGMODE, 1)

    -- ECM 开关
    elseif command == Keys.ActiveJamming then
        params_h.ECM_STATUS[2] = 1 - params_h.ECM_STATUS[2]

    -- 翼尖烟雾
    elseif command == Keys.PlaneWingtipSmokeOnOff then
        smokeOnOff(9)
        smokeOnOff(10)

    -- 切换机炮
    elseif command == Keys.GunMode and params_h.ATK_MODE[2] > 0 then
        params_h.GUN_MODE[2] = 1 - params_h.GUN_MODE[2]

    -- 机舱紧急抛弃
    elseif command == Keys.EmergJettion and get_elec_primary_ac_ok() then
        -- 依次检查各舱门状态，若开启则抛弃对应挂架
        if aircraftArgVal.leftDoor[2]  > 0.99 then emergJettion(0) end
        if aircraftArgVal.rightDoor[2] > 0.99 then emergJettion(1) end
        if aircraftArgVal.mainDoor[2]  > 0.99 then
            for _, idx in ipairs({2,3,4,5,6,7}) do emergJettion(idx) end
        end
        if Type then
            emergJettion( 8); emergJettion( 9)
            emergJettion(10); emergJettion(11)
        end
    end

    -- 同步主武器开火授权状态
    params_h.MASTER_MODE[2] = master_Arm
end

function update()
    if usingPylonIdx > 0 then
        params_h.WEAPON_DIS[2] = 1
    else
        params_h.WEAPON_DIS[2] = 0
    end
	--------------------------------------------------------------------------------
	-- 1. 只有当主交流电可用，才更新武器、IR、CCIP、CCRP 及 DLZ
	--------------------------------------------------------------------------------
    if get_elec_primary_ac_ok() then
        -- 挂架与武器信息
		updatePylonInfo()
        updateUsingPylon()
        updateAntiMslInfo()
        updateWPNPageInfo()
		-- 发射逻辑
        launchWpn()
		-- IR 导弹锁定/跟踪 HUD 更新
        update_ir_msl_status()
        -- CCIP（机炮弹道）更新
		updateCCIP()
		-- CCRP（抛投计算）更新
        update_ccrp()
		-- 攻击点管理
        updateATK_wpts()
		-- 机炮与激光炮射击处理
        updateGunFire()
        update_cannon_track()
		-- 雷达目标范围同步
        updateTarget()
		-- **新增：动态 DLZ（基于高度×迎头/尾追×地速插值）**
        updateDLZ_Dynamic()
        -- ECM 状态同步
        if params_h.ECM_STATUS[2] == 1 and not Weapon_System:get_ECM_status() then
            Weapon_System:set_ECM_status(true)
        elseif params_h.ECM_STATUS[2] == 0 and Weapon_System:get_ECM_status() then
            Weapon_System:set_ECM_status(false)
        end
    else
		-- 如果失去电源，确保 ECM 关闭
        if Weapon_System:get_ECM_status() then
            Weapon_System:set_ECM_status(false)
            params_h.ECM_STATUS[2] = 0
        end
    end
	--------------------------------------------------------------------------------
    -- 2. 弹仓/舱门装填动画
    --------------------------------------------------------------------------------
    if weaponLoading then
        if loadStationIdx == 1 then
            --EOTS安装完成
            aircraftArgVal.mainDoor[2]=Limit(aircraftArgVal.mainDoor[2]+0.02,0,1)
        elseif loadStationIdx == 7 then
            --主弹舱装弹完成
            aircraftArgVal.mainDoor[2]=Limit(aircraftArgVal.mainDoor[2]-0.02,0,1)
            aircraftArgVal.leftDoor[2]=Limit(aircraftArgVal.leftDoor[2]+0.02,0,1)
        elseif loadStationIdx == 8 then
            --左侧弹仓装弹完成
            aircraftArgVal.leftDoor[2]=Limit(aircraftArgVal.leftDoor[2]-0.02,0,1)
            aircraftArgVal.rightDoor[2]=Limit(aircraftArgVal.rightDoor[2]+0.02,0,1)
        elseif loadStationIdx == 9 then
            --右侧弹仓装弹完成
            aircraftArgVal.rightDoor[2]=Limit(aircraftArgVal.rightDoor[2]-0.02,0,1)
        end
    elseif params_h.WPN_ROOM_STATUS[2]==1 then
        --强制开启所有弹仓
        aircraftArgVal.mainDoor[2]=Limit(aircraftArgVal.mainDoor[2]+aircraftArgVal.mainDoor[3],0,1)
        aircraftArgVal.leftDoor[2]=Limit(aircraftArgVal.leftDoor[2]+aircraftArgVal.leftDoor[3],0,1)
        aircraftArgVal.rightDoor[2]=Limit(aircraftArgVal.rightDoor[2]+aircraftArgVal.rightDoor[3],0,1)
    end
    --------------------------------------------------------------------------------
    -- 3. 更新舱门绘制参数
    --------------------------------------------------------------------------------
    updateAircraftArgument()
    --------------------------------------------------------------------------------
    -- 4. 同步所有 params_h 到对应句柄
    --------------------------------------------------------------------------------
    for k, v in pairs(params_h) do
        if type(v[3])~="nil" then
            local min = v[5] or 0
            local max = v[6] or 1
            -- 平滑插值句柄
			if v[2] > v[3] then
                v[3] = Limit(v[3]+v[4],min,max)
            elseif v[2]< v[3] then
                v[3] = Limit(v[3]-v[4],min,max)
            end
            v[1]:set(v[3])
        else
            -- 直接赋值句柄
			v[1]:set(v[2])
        end
    end
	-- 5. 更新导弹 TOF 倒计时槽位
	update_missile_slots(update_time_step)
end

function CockpitEvent(event,value)
    if event == CptEvntNames.initChaffFlarePayload then
        params_h.GUN_COUNT[2] = 648
        weaponLoading = true
    elseif event == CptEvntNames.weaponRearmFirstStep then
        loadStationIdx = 0
    elseif event == CptEvntNames.weaponRearmSingleStepComplete then
        loadStationIdx = loadStationIdx +1
    elseif event == CptEvntNames.weaponRearmComplete then
        loadStationIdx = -1
        weaponLoading = false
    end
end

need_to_be_closed = false