Skip to content

[Bug]: 配件data文件中 aim_inaccuracy、sneak_inaccuracy、lie_inaccuracy 在未同时填写 inaccuracy 时不会被加载 #700

Description

@13ethovn

我已确认 ...

  • 我正在使用最新版的tacz
  • 无法在不安装tacz时复现

Minecraft和模组加载器版本

Minecraft 1.20.1, forge 47.3.22

tacz的版本

1.1.8-hotfix

Related Mods

tacz-1.20.1-1.1.8-hotfix

Description

配件 JSON 中的 aim_inaccuracysneak_inaccuracylie_inaccuracy 看起来已经被 InaccuracyModifier 支持,但如果同一个 JSON 中没有同时填写顶层字段 inaccuracy,这些字段实际上不会被加载。

例如,这种写法可能不会生效:
{
"aim_inaccuracy": {
"multiplier": 0.88
}
}

但这种写法可以生效:
{
"inaccuracy": {
"multiplier": 1.0
},
"aim_inaccuracy": {
"multiplier": 0.88
}
}

这里添加的 inaccuracy 并不是为了修改腰射散布,因为 multiplier: 1.0 是默认值;它只是为了让加载器调用 InaccuracyModifier.readJson,从而使同一文件中的 aim_inaccuracy 被读取。

原因:

AttachmentDataManager.parseJson 中,配件 modifier 只有在 JSON 中存在 modifier 的主字段名,或者存在 getOptionalFields() 返回的旧字段名时,才会调用 readJson

AttachmentPropertyManager.getModifiers().forEach((key, value) -> {
String json = getGson().toJson(element);
if (!element.isJsonObject()) {
return;
}
JsonObject jsonObject = element.getAsJsonObject();
if (jsonObject.has(key)) {
JsonProperty property = value.readJson(json); property.initComponents(); data.addModifier(key, property); } else if (jsonObject.has(value.getOptionalFields())) { JsonProperty property = value.readJson(json);
property.initComponents();
data.addModifier(key, property);
}
});

对于 InaccuracyModifier 来说,它注册到 MODIFIERS 中时使用的 key 是:InaccuracyModifier.ID
InaccuracyModifier.ID 来自:GunProperties.INACCURACY.name()
GunProperties.INACCURACY 的字段名是:GunProperty.of("inaccuracy", ...)

所以 InaccuracyModifier 的主字段名是:"inaccuracy"
同时,当前 InaccuracyModifier.getOptionalFields() 只返回:"inaccuracy_addend"

因此,如果配件 JSON 只包含:"aim_inaccuracy", "sneak_inaccuracy", "lie_inaccuracy"
而不包含:"inaccuracy"或"inaccuracy_addend"
那么这两个判断都会失败:
jsonObject.has("inaccuracy") == false
jsonObject.has("inaccuracy_addend") == false
结果就是 InaccuracyModifier.readJson(json) 不会被调用。

为什么这看起来像是bug?
InaccuracyModifier.Data 中已经显式定义了这些字段:

@SerializedName("aim_inaccuracy")
private Modifier aimInaccuracy;

@SerializedName("sneak_inaccuracy")
private Modifier sneakInaccuracy;

@SerializedName("lie_inaccuracy")
private Modifier lieInaccuracy;

并且 readJson 在被调用后,也确实会读取并处理它们。
所以问题似乎不在 InaccuracyModifier 的解析逻辑本身,而是在 AttachmentDataManager 判断是否调用该 modifier 的触发条件上。

预期行为

如果配件 JSON 中存在以下任意字段:

"inaccuracy"
"aim_inaccuracy"
"sneak_inaccuracy"
"lie_inaccuracy"
"inaccuracy_addend"

都应该触发 InaccuracyModifier.readJson
并且诸多枪包都存在只修改中间三个属性而没有出现"inaccuracy"或"inaccuracy_addend"的配件数据,而这些属性都不会生效。

可能的修复方式

一种可能的修复方式是让 InaccuracyModifier.getOptionalFields() 支持多个字段,或者让 AttachmentDataManager 检查 modifier 声明的所有可识别字段。

对于 InaccuracyModifier,它应该在以下字段任意一个存在时被触发:
inaccuracy
aim_inaccuracy
sneak_inaccuracy
lie_inaccuracy
inaccuracy_addend

也可以考虑让 modifier 提供一个字段名列表,而不是目前的“一个主字段名 + 一个旧版兼容字段名”。

临时解决方案

目前可以在配件 JSON 中添加一个默认的 inaccuracy 字段来强制触发加载:

"inaccuracy": {
"multiplier": 1.0
}

这样不会改变腰射散布数值,但可以让同一文件中的 aim_inaccuracysneak_inaccuracylie_inaccuracyInaccuracyModifier.readJson 读取并生效。

复现步骤

  1. 打开任意枪包的"data\tacz\data\attachments" ,选择一个你想修改的.json文件,添加或修改其中的 aim_inaccuracysneak_inaccuracylie_inaccuracy 字段,但删除 inaccuracy 字段,保存并退出。
  2. 开始游戏,将刚刚你修改过数据的配件安装到枪械上,打开左侧的详细数据,你会发现aim_inaccuracysneak_inaccuracylie_inaccuracy 与安装此配件前没有变化。
  3. 在你刚刚修改的.json内,添加
    "inaccuracy": {
    "multiplier": 1.0
    },
    (如果在文件末添加则删除逗号)
  4. 退出并重新进入存档或使用/reload指令,然后再次安装此配件,你会发现aim_inaccuracysneak_inaccuracylie_inaccuracy 的修改开始生效。

日志和崩溃报告

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions