占位符组 (Placeholders)
基本信息
| 属性 | 值 |
|---|---|
| 所属 modid | betterquesting(核心模组) |
| 涉及注册项 | 1 物品 + 1 实体 + 1 流体 + 1 占位方块物品(见下表) |
| 注册位置 | BetterQuesting.java:98-103(流体 / 4 个物品)、BetterQuesting.java:153(实体) |
| 中文名 | 物品 占位符 / 样板占位符(zh_CN.lang) |
BetterQuesting 核心共注册 4 个占位对象,分属 3 种注册表(物品 / 实体 / 流体)。它们属于同一族:整合包作者删掉某个 mod 或某个物品后,已保存的任务数据仍引用着原 ID,加载时 BetterQuesting 用这些占位对象把缺失内容"冻"住,不崩溃也不丢数据;等 mod 装回来,占位符会自动还原成原物品。
| 成员 | 注册名 | 类 | 注册方式 | 承载的原始数据 |
|---|---|---|---|---|
| 物品占位符 | betterquesting:placeholder |
api.placeholders.ItemPlaceholder |
GameRegistry.registerItem(ItemPlaceholder.placeholder, "placeholder")(BetterQuesting.java:100) |
NBT orig_id(字符串)、orig_meta(整数)、orig_tag(复合标签) |
| 样板占位符 | betterquesting:pattern_placeholder |
items.ItemPatternPlaceholder |
GameRegistry.registerItem(patternPlaceholder, "pattern_placeholder")(BetterQuesting.java:103) |
无(空实现,仅作图案/样板用途的哑物品) |
| 实体占位符 | placeholder(EntityRegistry 名) |
api.placeholders.EntityPlaceholder |
EntityRegistry.registerModEntity(EntityPlaceholder.class, "placeholder", 0, this, 16, 1, false)(BetterQuesting.java:153) |
NBT 键 original(复合标签) |
| 流体占位符 | betterquesting.placeholder(Fluid 名) |
api.placeholders.FluidPlaceholder |
FluidRegistry.registerFluid(FluidPlaceholder.fluidPlaceholder)(BetterQuesting.java:98) |
无 NBT,构造函数仅 super("betterquesting.placeholder") |
表中的
GameRegistry/EntityRegistry/FluidRegistry均为 Forge FML 类(cpw.mods.fml.common.registry.*、net.minecraftforge.fluids.FluidRegistry),不在本仓库源码内 —— 例如EntityRegistry由BetterQuesting.java:41的import cpw.mods.fml.common.registry.EntityRegistry;引入,调用点在:153。它们的行为由 Forge 提供,本条目只引用其调用形式,不描述其内部语义。
另有 TaskPlaceholder / FactoryTaskPlaceholder 与 RewardPlaceholder / FactoryRewardPlaceholder(api/placeholders/tasks/、api/placeholders/rewards/)—— 这两个不是 GameRegistry 注册项,而是任务/奖励工厂的兜底类型,见 任务类型注册表 与 奖励框架。
功能
物品占位符的自愈机制
ItemPlaceholder.onUpdate 是整组的核心:每 100 tick(5 秒)在玩家背包内的该物品上跑一次(ItemPlaceholder.java:49-66)。逻辑为:
- 取出 NBT 的
orig_id,从Item.itemRegistry反查Item对象i m取「当前stack.getItemDamage()(若 > 0)否则orig_meta」—— 意味着玩家若手动给占位符打了耐久/损伤值,会以该值优先- 若
i != null(原物品已回归),构造new ItemStack(i, stack.stackSize, m),把orig_tag(可空)拷回,然后player.inventory.setInventorySlotContent(slot, converted)完成替换
失败路径同样重要:NBT 缺失时 tooltip 直接显示 ERROR: Original information missing!(ItemPlaceholder.java:32);NBT 存在但只显示 Original ID: <orig_id>/<orig_meta>(ItemPlaceholder.java:36-41)。
实体占位符
EntityPlaceholder 是一个空的 Entity(entityInit() 空实现),内部持有一个装着 ItemPlaceholder.placeholder 的 EntityItem(EntityPlaceholder.java:15-20)。它只做一件事:把任意 NBT 原样存进/读出 original 键(readEntityFromNBT / writeEntityToNBT),供导入器在转换失败时兜底。
流体占位符
FluidPlaceholder extends Fluid,构造即 super("betterquesting.placeholder"),没有任何覆写(FluidPlaceholder.java)。它纯粹是「一个已知名字的、能进 FluidRegistry 的合法 Fluid 对象」,用于给缺失流体一个可引用的句柄。其图标在纹理拼接阶段注册:EventHandler.onTextureStitch 在 map.getTextureType() == 0 时注册 betterquesting:fluid_placeholder(handlers/EventHandler.java 末尾)。
样板占位符
ItemPatternPlaceholder 只有构造函数(设贴图名、设 unlocalized 名、设创造标签),类体内无任何其他方法覆写。它是一个"纯哑物品",供整合包在任务/图案数据中引用一个永远存在的稳定 ID。
数值
| 数值名 | 值 | 来源 |
|---|---|---|
| 物品占位符自愈周期 | 每 100 tick(5 秒) | world.getTotalWorldTime() % 100 != 0 提前返回(ItemPlaceholder.java:52) |
| 自愈作用范围 | 仅玩家背包槽位 | onUpdate 的 entity instanceof EntityPlayer 判断(ItemPlaceholder.java:51) |
| 实体 ID(mod 内部) | 0;更新频率 16;追踪范围 1;是否发送 spawn packet = false | EntityRegistry.registerModEntity(..., 0, this, 16, 1, false)(BetterQuesting.java:153) |
| 实体贴图 | 无(entityInit() 空实现,无渲染注册) |
EntityPlaceholder.java:38-40 |
| 流体容量 / 密度等 | 未覆写,全部取 Fluid 默认值 |
FluidPlaceholder.java 无覆写方法 |
交互
| 触发 | 行为 |
|---|---|
| 物品占位符被放入背包 | 每 5 秒尝试还原为原物品;成功则静默替换 |
| 物品占位符悬停 | 显示 Original ID: <域:名>/<meta>;无 NBT 时显示英文错误串 |
| 物品占位符在容器(箱子/机器)内 | 不会自愈 —— onUpdate 只在玩家背包触发 |
| 实体占位符 | 无交互;仅在世界数据与导入流程中作为 NBT 载体 |
| 流体占位符 | 无玩家交互 |
| 样板占位符 | 无任何行为 |
资源文件
| 路径 | 用途 |
|---|---|
assets/betterquesting/textures/items/placeholder.png |
物品占位符 |
assets/betterquesting/textures/items/pattern_placeholder.png |
样板占位符 |
assets/betterquesting/textures/blocks/fluid_placeholder.png |
流体占位符 |