占位符组 (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)。逻辑为:

  1. 取出 NBT 的 orig_id,从 Item.itemRegistry 反查 Item 对象 i
  2. m 取「当前 stack.getItemDamage()(若 > 0)否则 orig_meta」—— 意味着玩家若手动给占位符打了耐久/损伤值,会以该值优先
  3. 若 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 流体占位符

相关条目

  • 任务类型注册表 - FactoryTaskPlaceholder / FactoryRewardPlaceholder 同样是兜底类型,但走的是另一套工厂注册表
  • 扩展示例加载器 - 占位符类由核心 modid 提供,附属包通过它拿到任务/奖励注册表