奖励框架 (Reward Framework)
基本信息
| 属性 | 值 |
|---|---|
| 注册表 | betterquesting.questing.rewards.RewardRegistry(单例 INSTANCE) |
| 存储 | betterquesting.questing.rewards.RewardStorage(SimpleDatabase<IReward>) |
| 接口 | betterquesting.api.questing.rewards.IReward |
| 基类 | betterquesting.api.questing.rewards.AbstractReward |
| 占位类型 | api.placeholders.rewards.RewardPlaceholder / FactoryRewardPlaceholder |
| API 键 | ApiReference.REWARD_REG(ExpansionLoader.java:33) |
| 核心自带具体奖励类型 | 0 个 |
功能
奖励框架与任务框架完全对称(TaskRegistry : TaskStorage : ITask 对应 RewardRegistry : RewardStorage : IReward),但有一个关键差异:核心 modid betterquesting 不提供任何具体的奖励类型。
grep -rln 'implements .*IReward' src/main/java/betterquesting 只命中 RewardRegistry、RewardStorage 与 RewardPlaceholder 三个文件 —— 前两个是框架,第三个是兜底占位。RewardRegistry 自身没有任何 rewardReg.register(...) 调用。
6 个具体奖励类型由**同仓库内的另一个 modid bq_standard(Standard Expansion)**注册,位置 bq_standard/core/proxies/CommonProxy.registerExpansion()(CommonProxy.java:76-81):
| 工厂类 | 奖励类 | 文件 |
|---|---|---|
FactoryRewardItem |
RewardItem |
bq_standard/rewards/RewardItem.java |
FactoryRewardCommand |
RewardCommand |
bq_standard/rewards/RewardCommand.java |
FactoryRewardXP |
RewardXP |
bq_standard/rewards/RewardXP.java |
FactoryRewardScoreboard |
RewardScoreboard |
bq_standard/rewards/RewardScoreboard.java |
FactoryRewardChoice |
RewardChoice |
bq_standard/rewards/RewardChoice.java |
FactoryRewardQuestCompletion |
RewardQuestCompletion |
bq_standard/rewards/RewardQuestCompletion.java |
这些属于 bq_standard 而非 betterquesting,且 BQ_Standard 声明 dependencies = "required-after:betterquesting"(bq_standard/core/BQ_Standard.java:34)。本分类只文档化核心框架;具体奖励类型的字段语义无法核实(需在 bq_standard 分类下另行成文,本轮不覆盖)。
注册表行为
RewardRegistry.register() 的校验与 TaskRegistry 同构(RewardRegistry.java:27-40):拒绝 null 工厂、拒绝 null 名字、拒绝重名或同实例重复注册。
createNew(ResourceLocation) 有一处兜底分支(RewardRegistry.java:57-62):若请求名字等于 FactoryRewardPlaceholder.INSTANCE.getRegistryName(),直接用占位工厂创建,完全绕过注册表查找。这保证奖励数据里的未知条目不会导致加载失败。
RewardStorage.readFromNBT 在创建后发现实例是 RewardPlaceholder 时,会进一步从 orig_data 标签中读出原始 rewardID(RewardStorage.java:47-50),即占位符会记住自己顶替的是哪种奖励。
存档格式
RewardStorage.writeToNBT(NBTTagList, List<Integer> subset) 为每条奖励追加一个 NBTTagCompound,含三个字段(RewardStorage.java:26-31):
| NBT 字段 | 类型 | 含义 |
|---|---|---|
rewardID |
字符串 | rew.getValue().getFactoryID().toString(),用于重建 |
index |
整数 | rew.getID(),恢复数据库内的原始索引 |
| 其余 | 复合标签 | IReward.writeToNBT(...) 的自定义数据 |
readFromNBT 中 index 缺失时以 -1 处理(jsonReward.hasKey("index", 99) ? ... : -1),即由数据库自行分配新索引。
writeToNBT声明了subset参数(@Nullable List<Integer>)但方法体内从未读取它 —— 与LifeDatabase.writeToNBT对users参数的处理不同(后者有if (users != null && !users.contains(entry.getKey())) continue;)。这属于源码中的未使用参数,不是本 wiki 推测出的行为。
数值
| 数值名 | 值 |
|---|---|
| 核心自带具体奖励类型 | 0 |
bq_standard 提供的具体奖励类型 |
6 |
| 占位奖励类型 | 1(RewardPlaceholder,不占注册表槽位) |
| 每条奖励的存档字段数 | 3(rewardID / index / 奖励自定义 NBT) |
| 未使用参数 | writeToNBT 的 subset |