【Payday2】收获日2 Mod制作教程: CF连杀图标和连杀语音Mod

224次阅读
没有评论

共计 14208 个字符,预计需要花费 36 分钟才能阅读完成。

本文将介绍收获日 2 的功能性脚本 mod 制作流程,以本人制作的 CF 连杀图标和语音 mod 为例。Mod 游戏预览点 这里。Mod 下载地址:https://modworkshop.net/mod/39464

项目仓库:https://github.com/Eysent/pd2-kill-streak

演示视频:https://www.bilibili.com/video/BV1DK411f7W6/

mod 前置库安装和前置 mod 安装

SuperBlt 下载地址:https://superblt.znix.xyz/

SuperBLT 是 Payday 2 游戏的一个插件框架,它允许玩家安装和运行各种自定义 MOD 来增强游戏体验。它提供了更好的稳定性和性能,并且支持更多的功能和 MOD。在上述网址的安装步骤里有详细说明:把下载的 dll 文件放到游戏根目录下,运行游戏会弹出下载对话框。完成后就出现了 mods 文件夹,里边就是存放各种 mod 文件的位置。
【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

几乎所有的 SuperBLT 提供的 Lua 函数都有注释,在像 VS Code 这样的编辑器中工作时会显示提示。关于 BLT 功能的总体概述,请参见vanilla BLT 的文档

由 SuperBLT 添加的功能的文档可以在网站导航菜单中找到。

除了 SuperBlt,此 mod 还依赖于 HopLib。这个库包含了很多实用的函数,方便我们 mod 功能的实现。下载后,解压到\PAYDAY 2\mods 文件夹下。

如下所示:
【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

另外,对于需要写脚本的 mod 来说,我推荐你下载一份源码来进行参考,这将会有利于你的开发工作。仓库地址:https://github.com/mwSora/payday-2-luajit

关于调试和问题定位:如果游戏崩溃了,你可以在 C:\Users\ 你的用户名 \AppData\Local\PAYDAY 2 下找到 crash.txt 文件,里边有你崩溃的原因说明。

如果没有崩溃,但是没有你预期的效果,你可以在 PAYDAY 2\mods\logs 查看日志文件,如果需要还可以 mod 中使用 blt.log 来打印信息。

创建 mod 文件

\PAYDAY 2\mods 文件夹下新建一个 Kill streak 文件夹,这就是我们 mod 文件存放的位置。在其中新建一个assets 文件夹,里边将存放我们用到的资源,如图片,语音等等。另外新建一个mod.txt,这个文件用于说明我们 mod 的名称、作者、用到的库文件等。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

assets 文件夹

在此文件夹中包含了 mod 所需的美术资源或者声音资源等。文件夹的结构如下所示,其中 assets.xml 文件中描述了资源存放的位置。
【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

killicons文件夹中包含了连杀图标文件,格式后缀是 .texture。可以用其他软件编辑.dds 文件最后再改成.texture 后缀。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

这个文件包含了所需的连杀图标,所以 mod 的实现思路很简单,在对应的击杀数时播放对应的语音和展示对应的图标。Mod 所需的资源可以直接从我的项目中复制。(这里可以把图标安排的更紧凑以节省空间,但我不会,所以就只能这样了)

在确定好资源文件后,我们在kill streak 文件夹中新建一个supermod.xml, 用来告诉游戏加载我们的资源。

<?xml version="1.0"?>
<mod>
    <:include src="assets/assets.xml"/>
</mod>

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

编辑 mod.txt 如下,里边包含了 mod 的基本信息:

{
    "name" : "KillStreak",
    "author" : "Eysent",
    "blt_version" : 2.3,
    "hooks" : []}

此时打开游戏,就可以看到新建的 mod 了,只不过还没添加关键代码,是一个空 mod。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

实现基础图片显示

新建两个文本文档,分别重命名为 KillStreakPanel.luaPlayerManager.lua

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

下面我们先对核心功能代码文件进行说明。在 KillStreakPanel.lua 中包含对连杀图标的切换控制、语音的播放等内容。

编辑 KillStreakPanel.lua 文件,添加如下代码

KillStreakPanel = KillStreakPanel or class() 

function KillStreakPanel:init(hud) -- 初始化方法
    self._full_hud = hud
    self.kills = 0         -- 当前的连杀数
    self._headshot = false -- 是否是爆头击杀

    -- 图像绘制的面板定义
    self._kill_panel = self._full_hud:panel({
        name = "kill_panel", 
        alpha = 0,   -- 不透明度为 0,就是看不见 不然一开始就会有图标显示
        layer = 100,
    })

    -- 设定哪一个图标,初始化选择第一个图标;_kill_icon 是绘制在_kill_panel 上的
    self._kill_icon = self._kill_panel:bitmap({
        vertical = "center",    -- 居中
        align = "center",
        name = "kill_icon",
        texture = "guis/textures/killstreak/killicons/streak",  -- 资源位置
        texture_rect = {0,0,450,450},   -- 选择文件中的显示区域方框大小及位置,这里框住了第一个图标
        blend_mode      = "normal",
        alpha = 1,        -- 透明度
        w = 450 ,        -- 显示的长宽高,可以缩放或放大
        h = 450 ,
        layer = 4
    })
    self:Set_kill_icon()  -- 根据连杀数更改设定显示的图标
    self:MakeFine()       -- 调整图标位置

end

下面添加 Set_kill_icon()MakeFine() 函数,在文件中添加以下代码:

function KillStreakPanel:Set_kill_icon()
    local index = self.kills        -- 判断用哪个图标的变量
    if self.kills == 1 and self._headshot then -- 第一个击杀并且是爆头
        if math.random() > 0.7 then     -- 没办法根据子弹命中位置选用哪个爆头图标,选用概率判断
            index = 8                   -- 有 0.3 的概率选用黄金爆头
        else
            index = 9                   -- 0.7 的概率选用白金爆头
        end

    elseif self.kills >7 then       -- 连杀图标最多只有这么多
        index = 7
    end

    local x = 0+450*(index-1)       -- 根据 index 判断方框的位置

    self._kill_icon:set_texture_rect(x, 0, 450, 450) -- 根据方框更改贴图
end

function KillStreakPanel:MakeFine()  -- 在_kill_panel 居中显示
    self._kill_panel:set_size(self._kill_icon:w() + 2, self._kill_icon:h() + 2)
    self._kill_icon:set_center(self._kill_panel:w() / 2, self._kill_panel:h() / 2)
    self._kill_panel:set_center(self._full_hud:center_x(), self._full_hud:center_y())    
end

好了现在我们需要告诉脚本我们什么时候统计并更新击杀数,以及进行初始化工作。编辑 PlayerManager.lua 文件并添加如下代码:

dofile(ModPath .. "/KillStreakPanel.lua") -- 执行 KillStreakPanel.lua

--             Hook 文件名          函数名          自定义名称
Hooks:PostHook(PlayerManager, "on_killshot", "KillStreakHook1", function()
    KillStreakPanel.kills = KillStreakPanel.kills + 1
    KillStreakPanel:Set_kill_icon()  -- 更换图标
    KillStreakPanel._kill_panel:set_alpha(1)  -- 不透明度为 1,这样才看得见
end)
Hooks:PostHook(PlayerManager, "on_lethal_headshot_dealt", "KillStreakHook2", function()
    KillStreakPanel._headshot = true
end)

-- 在 hudmaneger 的 init_finalize 函数执行后调用该代码,完成初始化
Hooks:PostHook(HUDManager,"init_finalize","killstreak_createhud",function(self,...)
    KillStreakPanel = KillStreakPanel:new(managers.gui_data:create_fullscreen_workspace():panel())
end)

另外,我们用到了 Hook,那就需要在 mod.txt 文件中添加我们用到的 Hook。

{
    "name" : "KillStreak",
    "author" : "Eysent",
    "blt_version" : 2.3,
    "hooks" : [{"hook_id" : "lib/managers/menumanager", "script_path" : "PlayerManager.lua"},
        {"hook_id" : "lib/managers/playermanager", "script_path" : "PlayerManager.lua"}
        {"hook_id" : "lib/managers/hudmanager", "script_path" : "PlayerManager.lua"}
    ]
}

Hook 你可以理解为在系统对应的函数调用后调用你自己的代码,也就是决定你的代码什么时候工作。具体的函数列表可以参考第一节末尾提到的源码。比如打开我们下载好的源码,在 \payday-2-luajit\pd2-lua\lib\managers 目录下可以看到很多文件,其中就包含了我们在中调用的 Hooklib/managers/hudmanager等。打开可以查看其包含哪些代码:

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

第 189 行就是我们在 PlayerManager.lua 中初始化 KillStreakPanel 的函数。

好了,言归正传,现在我们打开游戏就可以看到击杀图标和它的切换了。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

好,现在我们以看到图标会随着击杀数的改变而改变了。但是新的问题来了,我们没有设置连杀数的清零机制,图标也不会消失,图标的大小和位置都需要调整。这些问题我们将在后文中解决。

增加图片的消失动画

在前文我们可以看到 mod 已经实现了,图片的展示功能以及根据击杀数切换图片显示的功能。但是仍然缺失图片的消失动画和击杀数一段时间后清零的机制。本小节将解决这两个问题。图片的位置调整在后文将通过菜单设置选项来完善。

首先来着手处理图片的渐变消失效果,在 KillStreakPanel.lua 中添加一个函数,它的功能就是添加渐变效果:

function KillStreakPanel:Show_fading(rect)
    -- fadetime 是开始渐变消失之前的持续时间
    local fadetime = 3
    local wait_t = fadetime

    local t = 0.5 -- 从完全不透明到完全消失的时间

    -- 展示图层
    self._kill_panel:set_alpha(1)
    -- 等待 anim_t 秒
    while wait_t > 0 do
        wait_t = wait_t - coroutine.yield()
    end

    -- fade animation
    while t > 0 do
        t = t - coroutine.yield()
        local n = math.sin((t / 2) * 350)       
        self._kill_panel:set_alpha(math.lerp(0, 1, n))
    end

    self.kills = 0
    self._kill_panel:set_alpha(0)
    self._kill_panel:set_x(self._full_hud:center_x())
end

在此函数中,击杀图标出现的 fadetime 秒内不会有渐变消失的效果,在此期间可以正常切换击杀图标。之后的 0.5s 内击杀图标才会慢慢消失,并且会把击杀数清零。这样击杀图标消失后可以再次触发从 0 杀开始的图片切换循环。现在我们有了渐变的函数,还需要一个调用渐变动画的函数。再新写一个函数如下:

function KillStreakPanel:SetKills()
    self:Set_kill_icon()

    self._headshot = false  -- 已经有击杀了,就不能再显示爆头图标了
    self:MakeFine()

    self._kill_panel:stop()
    self._kill_panel:animate(callback(self, self, "Show_fading"))
end

另外再修改 PlayerManager.lua 中的 Hook 调用函数KillStreakHook1

Hooks:PostHook(PlayerManager, "on_killshot", "KillStreakHook1", function()
    KillStreakPanel.kills = KillStreakPanel.kills + 1
    KillStreakPanel:SetKills()
end)

好,保存,运行游戏来看看效果吧!
【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

嗯,效果不错,但是好像有点不得劲。图片突然出现,感觉缺少一点打击感。那就再添加一个瞬间变大再复原,并来附加一个短暂的渐变。

添加如下函数:

function KillStreakPanel:Show_brust(panel)
    local t = 0
    local w = self._kill_icon:w()

    while t < 0.1 do
        t = t + coroutine.yield()
        local n = math.sin((t / 2) * 350)  
        local t_size = math.lerp(w, 2*w, n)

        -- 放大 icon 并居中,不然会以左上角为原点放大
        self._kill_icon:set_size(t_size,t_size)
        self._kill_icon:set_center(self._kill_panel:w() / 2, self._kill_panel:h() / 2)

        self._kill_panel:set_alpha(math.lerp(0, 1, n))
    end

    self._kill_panel:set_alpha(1)-- 保证完全显示
    self:Reset_icon() -- 回复原来大小并居中
end

function KillStreakPanel:Reset_icon()
    self._kill_icon:set_size(450 ,450)
    self:MakeFine()
end

完成上述函数后,还需要调用新加的动画效果,修改 SetKills() 如下:

function KillStreakPanel:SetKills()
    self:Set_kill_icon()

    self._headshot = false
    self:MakeFine()

    self._kill_panel:stop()

    self._kill_panel:animate(callback(self, self, "Show_brust"))
    self._kill_panel:animate(callback(self, self, "Show_fading"))
end

好,现在基本的击杀图标显示功能就实现了,接下来就是调整位置和大小了。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

添加菜单选项

我们当然可以直接在代码里修改图片的位置和大小,但这样可能不能适应其他用户的使用情况,比如安装了其他 HUD mod,可能会存在遮挡的情况。因此,我们需要添加一个游戏内的选项菜单来自定义这些选项,也方便后续控制新添加的变量。

在 Mod 目录下新建一个Menu.lua:

_G.KillStreak = _G.KillStreak or {}
KillStreak.ModPath = ModPath
KillStreak.SavePath = SavePath .. "KillStreak.txt"  -- 设置保存位置
KillStreak.LocPath = ModPath .. "loc/"              -- 本地化保存位置 方便翻译成多国语言
KillStreak.Opt = {} 
KillStreak.OptMenuId = "KillStreakOptions"

function KillStreak:Init()
    dofile(self.ModPath .. "/KillStreakPanel.lua")

    self:Load()

    self.Opt.fadetime = self.Opt.fadetime or 3    -- 后边的数字是默认设置
    self.Opt.pos = self.Opt.pos or 142
    self.Opt.scale = self.Opt.scale or 0.35
    self.Opt.alpha = self.Opt.alpha or 1.0

    HopLib:load_localization(KillStreak.LocPath, managers.localization)

    self.Panel = KillStreakPanel:new(managers.gui_data:create_fullscreen_workspace():panel())

    self.InitDone = true
end

function KillStreak:Save()
    local file = io.open(self.SavePath, "w+")
    if file then
        file:write(json.encode(self.Opt))
        file:close()
    end
end

function KillStreak:Load()
    local file = io.open(self.SavePath, "r")
    if file then
        self.Opt = json.decode(file:read("*all"))
        file:close()
    end
end

function MenuCallbackHandler:KillStreak_value(item)
    KillStreak.Opt[item._parameters.name:gsub("KillStreak_", "")] = item:value()
    KillStreak:Save()
    KillStreak.Panel:Reset_icon()
end

Hooks:Add("MenuManagerPopulateCustomMenus", "KillStreakOptions", function(self, nodes)
    if not KillStreak.InitDone then
        KillStreak:Init()
    end
    -- 添加各种选项
    MenuHelper:NewMenu(KillStreak.OptMenuId)
    MenuHelper:AddSlider({
        id = "KillStreak_fadetime",
        title = "KillStreak_fadetime_title",
        callback = "KillStreak_value",
        menu_id = KillStreak.OptMenuId,
        max = 60,
        min = 0.5,
        step = 0.1,
        show_value = true,
        value = KillStreak.Opt.fadetime,
    })      
    MenuHelper:AddSlider({
        id = "KillStreak_pos",
        title = "KillStreak_pos_title",
        callback = "KillStreak_value",
        menu_id = KillStreak.OptMenuId,
        max = 300,
        min = 16,
        step = 1,
        show_value = true,
        value = KillStreak.Opt.pos,
    })
    MenuHelper:AddSlider({
        id = "KillStreak_scale",
        title = "KillStreak_scale_title",
        callback = "KillStreak_value",
        menu_id = KillStreak.OptMenuId,
        max = 2.0,
        min = 0.1,
        step = 0.1,
        show_value = true,
        value = KillStreak.Opt.scale,
    })  
    MenuHelper:AddSlider({
        id = "KillStreak_alpha",
        title = "KillStreak_alpha_title",
        callback = "KillStreak_value",
        menu_id = KillStreak.OptMenuId,
        max = 1.0,
        min = 0.0,
        step = 0.1,
        show_value = true,
        value = KillStreak.Opt.alpha,
    })

    nodes[KillStreak.OptMenuId] = MenuHelper:BuildMenu(KillStreak.OptMenuId)
    MenuHelper:AddMenuItem(nodes.lua_mod_options_menu or nodes.blt_options, KillStreak.OptMenuId, "KillStreak_options_title", "KillStreak_options_desc")
end)

在 mod 目录中新建一个 loc 文件夹,里边放翻译文件,这里我们先创建简体中文的文件schinese.txt

{
    "KillStreak_options_title" : " 连杀图标 & 语音选项 ",
    "KillStreak_options_desc" : " 设定参数 ",
    "KillStreak_fadetime_title" : " 连杀持续时间 ",
    "KillStreak_pos_title" : " 连杀图标 y 轴偏移 ",
    "KillStreak_scale_title" : " 连杀图标缩放因子 ",
    "KillStreak_alpha_title" : " 图标透明度 ",
}

为了方便,这里统一把 KillStreakPanel 的实例化放在这里,所以对应的 PlayerManager.lua 也要修改,让它的代码更简洁。

Hooks:PostHook(PlayerManager, "on_killshot", "KillStreakHook1", function()
    KillStreak.Panel.kills = KillStreak.Panel.kills + 1
    KillStreak.Panel:SetKills()
end)
Hooks:PostHook(PlayerManager, "on_lethal_headshot_dealt", "KillStreakHook2", function()
    KillStreak.Panel._headshot = true
end)

因为更改了 Hook 相关代码,这里更新下mod.txt

{
    "name" : "KillStreak",
    "author" : "Eysent",
    "blt_version" : 2.3,
    "hooks" : [{"hook_id" : "lib/managers/playermanager", "script_path" : "PlayerManager.lua"},
        {"hook_id" : "lib/managers/menumanager", "script_path" : "Menu.lua"},
        {"hook_id" : "lib/states/ingameplayerbase", "script_path" : "Menu.lua"},
    ]
}

最后,我们把相关参数应用到以下几个函数中:

function KillStreakPanel:init(hud)
    self._full_hud = hud
    self.kills = 0
    self._headshot = false

    self._kill_panel = self._full_hud:panel({
        name = "kill_panel", 
        alpha = 0,
        layer = 100,
    })

    self._kill_icon = self._kill_panel:bitmap({
        vertical = "center",
        align = "center",
        name = "kill_icon",
        texture = "guis/textures/killstreak/killicons/streak",
        texture_rect = {0,0,450,450},
        blend_mode      = "normal",
        alpha = KillStreak.Opt.alpha,   -- 自定义参数
        w = 450 * KillStreak.Opt.scale,
        h = 450 * KillStreak.Opt.scale,
        layer = 4
    })
    self:Set_kill_icon()
    self:MakeFine()
end
function KillStreakPanel:MakeFine()
    self._kill_panel:set_size(self._kill_icon:w() + 2, self._kill_icon:h() + 2)
    self._kill_icon:set_center(self._kill_panel:w() / 2, self._kill_panel:h() / 2)
    self._kill_panel:set_center(self._full_hud:center_x(), self._full_hud:center_y() + KillStreak.Opt.pos)    -- Y 轴位置
end
function KillStreakPanel:Show_fading(rect)
    -- fadetime 是开始渐变消失之前的持续时间
    local fadetime = KillStreak.Opt.fadetime -- 持续时间
    local wait_t = fadetime

    local t = 0.5 -- 从完全不透明到完全消失的时间

    -- 展示图层
    self._kill_panel:set_alpha(1)
    -- 等待 anim_t 秒

    while wait_t > 0 do
        wait_t = wait_t - coroutine.yield()
    end

    -- fade animation
    while t > 0 do
        t = t - coroutine.yield()
        local n = math.sin((t / 2) * 350)       
        self._kill_panel:set_alpha(math.lerp(0, 1, n))
    end

    self.kills = 0
    self._kill_panel:set_alpha(0)
    self._kill_panel:set_x(self._full_hud:center_x())
end
function KillStreakPanel:Reset_icon()
    self._kill_icon:set_size(450*KillStreak.Opt.scale ,450*KillStreak.Opt.scale) -- 大小
    self:MakeFine()
end

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

击杀图标的部分告一段落,下边就是最后一步,添加击杀语音。

添加语音提示

首先,从网上准备语音素材,我找到了部分 CF 角色的语音包,大概有这几个:" 猎狐者 ", " 零 ", " 瞳 ", " 毛妹 "(不知道是谁,听起来有俄罗斯口音)," 夏日之兰 "," 奥摩 "," 飞虎队 "。不知道语音跟人对不对的上,毕竟我退坑很久了,大部分角色语音都没听过。每个角色都包含以下语音,通过名字很清楚了解到对应什么语音。如果你要自定义的话,替换同名文件就可以了。

【Payday2】收获日 2 Mod 制作教程: CF 连杀图标和连杀语音 Mod

关于语音的菜单部分,即 Menu.lua,这里就不贴出来了,和前文大同小异,只是多几个而已。在KillStreakPanel.lua 中添加的函数如下:

function KillStreakPanel:play_kill_sound()
    blt.xaudio.setup()
    local table_index = self.kills
    if self.kills ==1 and not self._headshot then
        return 
    elseif self.kills > 8 then 
        table_index = 8
    end
    local filename = self:get_sound_filename(table_index)
    local buffer = XAudio.Buffer:new(filename)

    table.insert(self._sound_sources,XAudio.Source:new(buffer))
end

function KillStreakPanel:update_sound_sources()
    for i, src in ipairs(self._sound_sources) do
        if src then
            if not src:is_closed() then
                blt.xaudio.setup()
                src:set_volume(KillStreak.Opt.volume/100)
                if managers.player:player_unit() then
                    src:set_position(managers.player:player_unit():position())
                end
            else
                src = nil
            end
        end
    end
end

function KillStreakPanel:play_voices(voice_type)
    if KillStreak.Opt.enable_sound then
        blt.xaudio.setup()

        local filename = self:get_sound_filename(voice_type)
        local buffer = XAudio.Buffer:new(filename)
        table.insert(self._sound_sources,XAudio.Source:new(buffer))
    end
end

function KillStreakPanel:get_sound_filename(voice_type)
    local filename = KillStreak.ModPath .. "assets/sounds/"
    --filename = filename .. "women1"
    filename = filename .. KillStreak.voices[KillStreak.Opt.voice_source].src
    filename = filename .. "/"
    filename = filename .. self._ogg_table[voice_type]
    return filename
end

修改部分函数:

function KillStreakPanel:init(hud)
    self._full_hud = hud
    self.kills = 0
    self._headshot = false
    self._ogg_table = {--[0] = "Knifekill.ogg"
        [1] = "Headshot.ogg",
        [2] = "MultiKill_2.ogg",
        [3] = "MultiKill_3.ogg",
        [4] = "MultiKill_4.ogg",
        [5] = "MultiKill_5.ogg",
        [6] = "MultiKill_6.ogg",
        [7] = "MultiKill_7.ogg",
        [8] = "MultiKill_8.ogg",
        [9] = "GrenadeKill.ogg",
        [10] = "Round_Start.ogg",
        [11] = "Fireinthehole_Grenade.ogg",
    }
    self._sound_sources = {}
   ... ... 
   ... ... 

end

function KillStreakPanel:SetKills()
    self:Set_kill_icon()
    if KillStreak.Opt.enable_sound then
        self:play_kill_sound()
    end

    self._headshot = false
    self:MakeFine()

    self._kill_panel:stop()

    self._kill_panel:animate(callback(self, self, "Show_brust"))
    self._kill_panel:animate(callback(self, self, "Show_fading"))
end

最后在 PlayerManager.lua 添加 扔手雷等其他语音函数并修改mod.txt

Hooks:PostHook(PlayerManager, "on_throw_grenade", "killsteak_play_grenade_voice", function()
    KillStreak.Panel:play_voices(11)
end)

Hooks:PostHook(HUDManager, "update", "killstreak_update_sound", function (self, ...)
    KillStreak.Panel:update_sound_sources(...)
end)

-- use voice manager to make character speak one setence at same time. see https://superblt.znix.xyz/doc/xaudio/
Hooks:PostHook(IngameMaskOffState, "at_exit", "killsteak_play_start_voice", function (self, ...)
    KillStreak.Panel:play_voices(10)
end)
{
    "name" : "KillStreak",
    "author" : "Eysent",
    "description" : "Add Crossfire kill streak icons and voices.",
    "blt_version" : 2.3,
    "hooks" : [{"hook_id" : "lib/managers/playermanager", "script_path" : "PlayerManager.lua"},
        {"hook_id" : "lib/managers/menumanager", "script_path" : "Menu.lua"},
        {"hook_id" : "lib/states/ingameplayerbase", "script_path" : "Menu.lua"},
        {"hook_id" : "lib/managers/hudmanager", "script_path" : "PlayerManager.lua"}
    ]
}

大功告成!希望你也可以自定义出自己的 MOD,如有问题或者反馈可以留言或者联系我。

视频演示地址:https://www.bilibili.com/video/BV1DK411f7W6/

正文完
 0
评论(没有评论)