我的助手KEN

我的助手KEN

这是一个供模组使用的库,用于通过Noesis操作BG3界面。它能让模组轻松找到特定的Noesis对象,并检测它们何时出现或消失。同时,它还会触发模组事件,使你的模组能够响应常见的界面事件,例如玩家打开设置。此应用旨在与KEN Noesis调试器配合使用。

我的助手肯是一个库,它主要做两件事:

  1. 通过为 UI 事件触发五个不同的自定义模组事件,让响应《博德之门3》UI 变化变得更加容易。
  2. 使用你可以从KEN 游戏内 Noesis 调试器复制的路径引用(字符串),让你更容易查找或监视 Noesis UI 对象。这意味着你无需编写代码来搜索 Noesis 对象,也无需进行任何形式的帧更新滥用来监视它们。你的助手肯会为大家处理所有这些帧更新滥用。

此应用旨在与 KEN Noesis 调试器 配合使用。你可以通过该调试器定位你感兴趣的 UI 元素,并获取可与我的助手肯一起使用的路径字符串。

注意Mazzle_Lib 也提供相同的功能。如果你同时安装了两者,MazzleLib 将让我的助手肯来完成实际工作。不过,这两个系统会广播不同的模组事件,因此你的模组需要选择其中一个来监听和依赖。

KEN 助手 API

模组事件订阅

我的助手肯在以下位置公开其 Noesis ModEvents:

Ext.ModEvents.KEN_Helper

我的助手肯仅在 MCM 设置中启用该模组时才发出这些事件。(如果未安装 MCM,则始终启用。)

订阅示例

Ext.ModEvents.KEN_Helper["UIOpened"]:Subscribe(function(e)
    if e.name == "CharacterSheet" then
        local ui_object = e.object
        -- 在此处编写你的客户端或服务器逻辑。
    end
end)

Noesis 事件

我的助手肯公开了以下五个事件名称:

  • UIOpened - 当 Noesis UI 元素变为可见时触发。
  • UIClosed - 当 Noesis UI 元素不再可见时触发。
  • ControllerModeChanged - 当游戏切换进入或退出控制器 UI 模式时触发。
  • MenuOpened
  • MenuClosed

UIOpened

  • 当特定 Noesis UI 元素变为可见时触发。
  • 客户端 ModEvent 负载:
{
    name = "Inventory",
    object = <noesis_object>,
}
  • object 是刚刚打开的 UI 的活动 Noesis 对象。
  • 服务器 ModEvent 负载:
{
    name = "Inventory",
    user = 1,
}

UIClosed

  • 当 Noesis UI 元素不再可见时触发。
  • 客户端 ModEvent 负载:
{
    name = "Inventory",
    object = <noesis_object>,
}
  • 如果在发出关闭事件之前 UI 完全消失,则 object 字段会被省略,仅返回 name。如果 UI 对象仅被标记为隐藏,则会包含 Noesis 对象引用。
  • 服务器 ModEvent 负载:
{
    name = "Inventory",
    user = 1,
}

ControllerModeChanged

  • 当游戏切换进入或退出控制器 UI 模式时触发。
  • 客户端 ModEvent 负载:
{
    enabled = true,
}
  • 服务器 ModEvent 负载:
{
    enabled = true,
    user = 1,
}

MenuOpened

  • 当《博德之门3》打开接管 UI 的界面元素(如游戏菜单、主菜单、过场动画和对话)时触发。
  • 此事件对于在 BG3 需要接管 UI 时隐藏你自己的 UI 非常有用。
  • 客户端 ModEvent 负载:
{
}
  • 服务器 ModEvent 负载:
{
    user = 1,
}

MenuClosed

  • 当被跟踪的游戏菜单状态关闭时触发。
  • 此事件对于在 BG3 接管 UI 后恢复你自己的 UI 非常有用。
  • 客户端 ModEvent 负载:
{
}
  • 服务器 ModEvent 负载:
{
    user = 1,
}
Noesis 解析器

我的助手肯还提供了一个实用函数,允许你仅使用描述对象路径的字符串来访问你想要的 Noesis UI 对象,例如:

"Ext.UI:GetRoot():Find('ContentRoot'):FindChildWithName('ModVerification')"

主要优点

  • 所需的路径字符串可以轻松地使用游戏内 KEN 调试器获取。
  • 你无需手动搜索 Noesis 对象并处理 Noesis 的各种特殊性问题。
  • 与其让多个模组各自进行帧更新滥用,我的助手肯会在一个中心位置处理所有滥用。
  • 你可以监视简单属性值从特定值发生变化的情况。

核心函数

要一次性获取 Noesis 对象:

local obj = Mods.KEN_Helper.KEN_NoesisPathResolver.Resolve(path)

要在 Noesis 对象出现或消失时获取回调:

local watch_id = Mods.KEN_Helper.KEN_NoesisPathResolver.ResolveAndMonitor(path, duration, onFound, onLost)

要取消之前设置的监视:

Mods.KEN_Helper.KEN_NoesisPathResolver.CancelMonitor(watch_id)

监视语义

  • ResolveAndMonitor(path, duration, onFound, onLost) 开始监视一个 KEN Noesis 路径。
  • onFound(obj) 当路径指向一个活动对象时触发。
  • onLost() 当对象消失时触发。
  • duration 可以是 nil-1,表示无限期。
  • CancelMonitor(handle) 移除监视,且不会调用 onLost()

要监视简单的属性变化,请使用以 FindChildWithProperty 作为最后一项的路径。我的助手肯将在项目存在且值发生变化时触发你的回调。未来,我可能会添加更通用的属性值变化监视功能。

监视示例

local handle =  Mods.KEN_Helper.KEN_NoesisPathResolver.ResolveAndMonitor(
    "Ext.UI:GetRoot():Find('ContentRoot'):FindChildWithName('ModVerification')",
    -1,
    function(obj)
        obj.DataContext.ContinueCommand:Execute()
    end
)

路径格式

大多数情况下,你不会手动编写这些路径。你会直接从 KEN 游戏内 Noesis 调试器中复制它们,然后将它们粘贴到 Resolve(...)ResolveAndMonitor(...) 中。

解析器目前支持以下路径操作:

  • 根访问:
    Ext.UI:GetRoot()
    
  • 名称查找:
    :Find('Name')
    :FindChildWithName('Name')
    :FindVisualChildWithName('Name')
    
  • 属性查找:
    :FindChildWithProperty('PropertyName', 'Value')
    :FindVisualChildWithProperty('PropertyName', 'Value')
    
  • 索引子项访问:
    :Child(1)
    :VisualChild(1)
    
  • 属性访问:
    .DataContext
    .FocusedElement
    other direct property reads
    
Ext.UI:GetRoot():Find('ContentRoot'):Find('HUD')
Ext.UI:GetRoot():Find('ContentRoot'):FindChildWithName('Dialog_box')
Ext.UI:GetRoot():Child(1):Child(3).DataContext
我的模组

游戏工具

  • EZ-Manipulator(用于移动、缩放、旋转角色、物品和风景的小工具)
  • Fricken FreeCam(自由移动摄像机)
  • MF Radio(游戏内收音机,可播放本机和下载的音乐)
  • RangeFinder(可视化移动范围和攻击,规划/自动化移动)
  • Tav's Journal(创建带有照片的游戏内日志,可导出和分享)
  • Tav's Clock(一个可以放置在任何地方的小时钟和会话计时器)

生活质量

库和外部工具

模组作者工具

支持本模组

如果你觉得这个模组有用,请考虑捐赠。

ko-fi