导航菜单

搜索并跳转到页面

生活日常2026年4月13日
DCS自动重置和手动重置地面目标的Lua脚本

久流

该DCS脚本可以对选定群组的飞机进行死亡后复活或者使用F10更换飞机、手动重置选定的地面目标。

前置:

需要提前安装DCS的MIST框架

1.克隆仓库:

 https://github.com/mrSkortch/MissionScriptingTools.git

2.导入项目 将克隆下来的项目文件夹放置在 DCS 的脚本目录中。

MissionScriptingTools(简称 Mist)是一个为 Digital Combat Simulator(DCS)设计的脚本工具集合。该项目旨在为 DCS 的脚本引擎提供额外的功能和数据库,以简化常见的脚本任务和挑战。Mist 包含了一系列的 Lua 函数和数据库,使得任务脚本编写更加高效和便捷。

lua
-- 定义可选的飞机类型和对应的模板群组名称local aircraftOptions = {    ["JF-17"] = "pve-1", -- pve-1 为飞机的群组    ["Su-27"] = "pve-2",    ["FA-18"] = "pve-3",    ["F-16C"] = "pve-4",    ["F-15C"] = "pve-5"}
-- 定义需要重置的地面目标群组local groupsToReset = {"地面-29", "地面-30", "地面-31"} --改为你地图种真实的地面目标
-- 状态管理local systemState = {    currentAircraft = "F-15C", --默认的群组    currentTemplate = aircraftOptions["F-15C"],    activeGroupName = nil,    isGroupAlive = false,    isSpawning = false,    pendingOperations = {},    templateStates = {} -- 跟踪每个模板的状态}
-- 初始化模板状态跟踪for aircraftType, templateName in pairs(aircraftOptions) do    systemState.templateStates[templateName] = {        lastActive = nil,        isTemplateActive = false,        spawnCount = 0    }end
-- 检查MIST框架可用性local function isMISTAvailable()    return mist and mist.respawnGroupend
-- 群组存在性检查local function isGroupActive(groupName)    if not groupName then        return false    end    local group = Group.getByName(groupName)    return group and group:isExist()end
-- 模板验证与恢复函数local function validateAndRecoverTemplate(templateName)    if not templateName then        env.error("模板验证: 模板名称为空")        return false    end
    -- 检查模板是否存在    local templateGroup = Group.getByName(templateName)    if not templateGroup then        env.warning("模板不存在: " .. templateName)
        -- 尝试通过MIST恢复模板        if isMISTAvailable() then            env.info("尝试通过MIST恢复模板: " .. templateName)            local success, result = pcall(function()                return mist.respawnGroup(templateName, true)            end)
            if success then                env.info("MIST模板恢复成功: " .. templateName)                -- 延迟验证恢复结果                timer.scheduleFunction(function()                    local restoredGroup = Group.getByName(templateName)                    if restoredGroup then                        systemState.templateStates[templateName].isTemplateActive = true                        env.info("模板恢复验证成功: " .. templateName)                        return true                    else                        env.warning("模板恢复验证失败: " .. templateName)                        return false                    end                end, nil, timer.getTime() + 3)                return true            else                env.error("MIST模板恢复失败: " .. tostring(result))                return false            end        else            env.error("MIST框架不可用,无法恢复模板: " .. templateName)            return false        end    end
    -- 模板存在,验证其状态    if templateGroup:isExist() then        systemState.templateStates[templateName].isTemplateActive = true        env.info("模板状态正常: " .. templateName)        return true    else        env.warning("模板存在但不可用: " .. templateName)        systemState.templateStates[templateName].isTemplateActive = false        return false    endend
-- 安全群组复制与激活local function safeCloneAndActivateGroup()    if systemState.isSpawning then        env.info("生成操作正在进行中,跳过重复请求")        return false    end
    systemState.isSpawning = true
    -- 验证MIST框架    if not isMISTAvailable() then        trigger.action.outText("错误:MIST框架未加载", 10)        systemState.isSpawning = false        return false    end
    local templateName = systemState.currentTemplate    local aircraftType = systemState.currentAircraft
    if not templateName then        trigger.action.outText("错误:当前模板为空", 10)        systemState.isSpawning = false        return false    end
    env.info("开始群组复制流程: " .. aircraftType .. " [" .. templateName .. "]")
    -- 销毁现有活跃群组    if systemState.activeGroupName and systemState.activeGroupName ~= templateName then        local existingGroup = Group.getByName(systemState.activeGroupName)        if existingGroup and existingGroup:isExist() then            env.info("销毁现有群组: " .. systemState.activeGroupName)            local success, err = pcall(function()                existingGroup:destroy()            end)            if success then                trigger.action.outText("清理完成", 3)            else                env.warning("销毁群组时出错: " .. tostring(err))            end        end        systemState.activeGroupName = nil        systemState.isGroupAlive = false    end
    -- 延迟执行    timer.scheduleFunction(function(args)        local tplName, acType = args[1], args[2]
        -- 验证模板状态        if not validateAndRecoverTemplate(tplName) then            trigger.action.outText("错误:模板准备失败 - " .. tplName, 10)            systemState.isSpawning = false            return nil        end
        env.info("执行MIST群组复制: " .. tplName)
        -- MIST调用        local success, result = pcall(function()            return mist.respawnGroup(tplName, true)        end)
        if not success then            env.error("MIST重生失败: " .. tostring(result))            trigger.action.outText("群组复制失败,5秒后重试", 10)
            -- 延迟重试机制            timer.scheduleFunction(function()                if not systemState.isGroupAlive and not systemState.isSpawning then                    env.info("重试群组复制")                    safeCloneAndActivateGroup()                end            end, nil, timer.getTime() + 5)
            systemState.isSpawning = false            return nil        end
        -- 更新系统状态        systemState.activeGroupName = tplName        systemState.templateStates[tplName].lastActive = timer.getTime()        systemState.templateStates[tplName].spawnCount = (systemState.templateStates[tplName].spawnCount or 0) + 1
        -- 延迟激活复制的群组        timer.scheduleFunction(function(activationArgs)            local groupName, aircraft = activationArgs[1], activationArgs[2]
            local newGroup = Group.getByName(groupName)            if newGroup and newGroup:isExist() then                -- 设置群组控制器                local controller = newGroup:getController()                if controller then                    controller:setOnOff(true)
                    -- 激活所有单元                    local units = newGroup:getUnits()                    if units and #units > 0 then                        for i, unit in ipairs(units) do                            if unit and unit:isExist() then                                local unitController = unit:getController()                                if unitController then                                    unitController:setOnOff(true)                                end                            end                        end                    end
                    systemState.isGroupAlive = true                    systemState.isSpawning = false
                    trigger.action.outText("✓ " .. aircraft .. " 就绪", 10)                    env.info("群组复制激活完成: " .. aircraft)
                    -- 记录成功状态                    systemState.templateStates[groupName].isTemplateActive = true                else                    env.warning("无法获取群组控制器: " .. groupName)                    systemState.isSpawning = false                end            else                env.warning("延迟激活时群组不存在: " .. groupName)                trigger.action.outText("激活失败,请检查模板: " .. groupName, 10)                systemState.isSpawning = false            end            return nil        end, {tplName, acType}, timer.getTime() + 2)
        return nil    end, {templateName, aircraftType}, timer.getTime() + 1)
    return trueend
-- 飞机切换函数local function switchAircraft(aircraftType)    if not aircraftOptions[aircraftType] then        trigger.action.outText("错误:无效的飞机类型: " .. (aircraftType or "nil"), 5)        return    end
    if systemState.currentAircraft == aircraftType then        trigger.action.outText("已是当前飞机: " .. aircraftType, 5)        return    end
    local previousAircraft = systemState.currentAircraft    local previousTemplate = systemState.currentTemplate
    trigger.action.outText("切换到: " .. aircraftType, 5)
    -- 更新当前选择    systemState.currentAircraft = aircraftType    systemState.currentTemplate = aircraftOptions[aircraftType]
    env.info("飞机切换: " .. previousAircraft .. " → " .. aircraftType)    env.info("模板切换: " .. (previousTemplate or "nil") .. " → " .. systemState.currentTemplate)
    -- 安全销毁前一个群组    if previousTemplate and previousTemplate ~= systemState.currentTemplate then        local previousGroup = Group.getByName(previousTemplate)        if previousGroup and previousGroup:isExist() then            env.info("销毁旧群组: " .. previousTemplate)            local success, err = pcall(function()                previousGroup:destroy()            end)            if success then                systemState.templateStates[previousTemplate].isTemplateActive = false            else                env.warning("销毁旧群组失败: " .. tostring(err))            end        end    end
    -- 清除活跃状态    systemState.activeGroupName = nil    systemState.isGroupAlive = false
    -- 延迟执行群组复制    timer.scheduleFunction(function()        safeCloneAndActivateGroup()    end, nil, timer.getTime() + 2)end
-- 地面目标重置函数local function resetAllGroups()    if not isMISTAvailable() then        trigger.action.outText("错误:MIST框架未加载!", 10)        return false    end
    local successCount = 0    local totalCount = 0
    for _, groupName in ipairs(groupsToReset) do        totalCount = totalCount + 1        -- MIST调用        local success, result = pcall(function()            return mist.respawnGroup(groupName, true)        end)
        if success then            successCount = successCount + 1            env.info("地面目标重置成功: " .. groupName)        else            env.info("地面目标重置失败: " .. groupName .. ": " .. tostring(result))        end    end
    trigger.action.outText("地面目标重置完成。成功重置: " .. successCount .. "/" .. totalCount ..                               " 个群组", 10)    return successCount > 0end
-- F10菜单创建函数local function createUnifiedF10Menu()    if not missionCommands then        env.error("missionCommands API不可用")        return false    end
    -- 菜单标识符    local MAIN_MENU_NAME = "服务器设置"
    -- 清除可能存在的旧菜单    pcall(function()        missionCommands.removeItem(MAIN_MENU_NAME)    end)
    -- 创建主菜单    local mainMenu = missionCommands.addSubMenu(MAIN_MENU_NAME)
    -- PVE飞机系统子菜单    local pveMenu = missionCommands.addSubMenu("PVE飞机系统", mainMenu)
    -- 飞机选择子菜单    local aircraftMenu = missionCommands.addSubMenu("选择飞机", pveMenu)
    -- 为每种飞机添加选择命令    for aircraftType, templateName in pairs(aircraftOptions) do        missionCommands.addCommand(aircraftType, aircraftMenu, function()            env.info("玩家选择飞机: " .. aircraftType)            -- 添加错误处理            local success, err = pcall(function()                switchAircraft(aircraftType)            end)            if not success then                env.error("飞机选择错误: " .. tostring(err))                trigger.action.outText("飞机选择失败,请检查日志", 5)            end        end)    end
    -- PVE系统功能命令    missionCommands.addCommand("系统状态", pveMenu, function()        local statusText = "=== PVE飞机系统状态 ===\n"        statusText = statusText .. "当前飞机: " .. systemState.currentAircraft .. "\n"        statusText = statusText .. "模板名称: " .. (systemState.currentTemplate or "无") .. "\n"        statusText = statusText .. "活跃群组: " .. (systemState.activeGroupName or "无") .. "\n"        statusText = statusText .. "群组状态: " .. (systemState.isGroupAlive and "存活" or "已摧毁") .. "\n"        statusText = statusText .. "生成状态: " .. (systemState.isSpawning and "进行中" or "空闲") .. "\n"        statusText = statusText .. "MIST框架: " .. (isMISTAvailable() and "可用" or "不可用")
        trigger.action.outText(statusText, 15)    end)
    missionCommands.addCommand("手动重生", pveMenu, function()        if not systemState.isSpawning then            trigger.action.outText("手动触发重生...", 5)            local success, err = pcall(function()                safeCloneAndActivateGroup()            end)            if not success then                env.error("手动重生错误: " .. tostring(err))                trigger.action.outText("手动重生失败", 5)            end        else            trigger.action.outText("系统繁忙,请稍候...", 5)        end    end)
    -- 目标重置子菜单    local targetMenu = missionCommands.addSubMenu("目标重置", mainMenu)
    -- 地面目标重置命令    missionCommands.addCommand("重置自由飞行区所有地面目标", targetMenu, function()        trigger.action.outText("开始重置地面目标...", 5)        local success, err = pcall(function()            resetAllGroups()        end)        if not success then            env.error("目标重置错误: " .. tostring(err))            trigger.action.outText("目标重置失败", 5)        end    end)
    env.info("F10菜单创建成功")    return trueend
-- 死亡事件处理world.addEventHandler({    onEvent = function(event)        if event.id == world.event.S_EVENT_DEAD then            local initiator = event.initiator            if initiator and initiator:getGroup() then                local group = initiator:getGroup()                local groupName = group:getName()
                if groupName == systemState.activeGroupName then                    env.info("检测到飞机死亡: " .. groupName)                    systemState.isGroupAlive = false                    systemState.templateStates[groupName] = systemState.templateStates[groupName] or {}                    systemState.templateStates[groupName].isTemplateActive = false
                    -- 5秒后重生                    timer.scheduleFunction(function(deadGroup)                        local success, err = pcall(function()                            if not systemState.isGroupAlive and not systemState.isSpawning then                                env.info("触发死亡重生: " .. deadGroup)                                safeCloneAndActivateGroup()                            end                        end)                        if not success then                            env.error("死亡重生错误: " .. tostring(err))                        end                        return nil                    end, groupName, timer.getTime() + 5)                end            end        end    end})
-- 状态监控与自动恢复local function startStateMonitor()    timer.scheduleFunction(function()        if systemState.activeGroupName and not isGroupActive(systemState.activeGroupName) then            if systemState.isGroupAlive and not systemState.isSpawning then                env.warning("状态监控: 检测到群组丢失 - " .. systemState.activeGroupName)                systemState.isGroupAlive = false                timer.scheduleFunction(function()                    local success, err = pcall(function()                        safeCloneAndActivateGroup()                    end)                    if not success then                        env.error("状态监控重生错误: " .. tostring(err))                    end                end, nil, timer.getTime() + 3)            end        end        return timer.getTime() + 5    end, nil, timer.getTime() + 5)end
-- 初始化系统local function initializeSystem()    env.info("初始化系统...")
    -- 验证所有模板    local validTemplates = 0    for aircraftType, templateName in pairs(aircraftOptions) do        if validateAndRecoverTemplate(templateName) then            env.info("✓ 模板就绪: " .. aircraftType)            validTemplates = validTemplates + 1        else            env.error("✗ 模板故障: " .. templateName)        end    end
    if validTemplates == 0 then        trigger.action.outText("错误:无可用飞机模板!", 10)        return false    end
    -- F10菜单    createUnifiedF10Menu()
    -- 启动状态监控    startStateMonitor()
    -- 初始生成    timer.scheduleFunction(function()        local success, err = pcall(function()            safeCloneAndActivateGroup()            trigger.action.outText("系统就绪 - 死亡后5秒自动重生", 10)        end)        if not success then            env.error("初始生成错误: " .. tostring(err))            trigger.action.outText("系统启动失败", 10)        end    end, nil, timer.getTime() + 5)
    return trueend
-- 启动timer.scheduleFunction(function()    local success, err = pcall(initializeSystem)    if not success then        env.error("系统初始化失败: " .. tostring(err))        trigger.action.outText("系统启动错误: " .. tostring(err), 10)    endend, nil, timer.getTime() + 10)
env.info("系统加载完成")
评论
0 个评论在此篇文章

暂无评论