经验瓶机 / 经验收集器 / 喷经验浴 / 自动铁砧 / 自动附魔台
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | OpenBlocks:xpbottler、OpenBlocks:xpdrain、OpenBlocks:xpshower、OpenBlocks:autoanvil、OpenBlocks:autoenchantmenttable |
| 对应类 | BlockXPBottler、BlockXPDrain、BlockXPShower、BlockAutoAnvil、BlockAutoEnchantmentTable(均在 openblocks.common.block) |
| TileEntity | 五个全部有(TileEntityXPBottler / TileEntityXPDrain / TileEntityXPShower / TileEntityAutoAnvil / TileEntityAutoEnchantmentTable) |
| 声明位置 | OpenBlocks.java:326(xpbottler)、:335(autoanvil)、:338(autoenchantmenttable)、:341(xpdrain)、:395(xpshower) |
这一组方块围绕**液体经验(XP Juice)**工作。经验液体定义在 OpenBlocks.java:504(Fluids.xpJuice,setLuminosity(10).setDensity(800).setViscosity(1500)),并由 OpenBlocks.java:605 的 FluidRegistry.registerFluid 实际注册,本地化键为 fluid.OpenBlocks.xpjuice(assets/openblocks/lang/en_US.lang)。
大小写混用提醒:经验液体的本地化前缀是大写的
OpenBlocks.,而贴图/资源域是小写的openblocks。
各方块构造参数
| 方块 | 材质 | 碰撞/渲染设置 | 贴图 |
|---|---|---|---|
| XP 瓶机 | Material.rock(BlockXPBottler.java:26) |
FOUR_DIRECTIONS |
6 面各一张,openblocks:xpbottler_front/top/sides/bottom/back(BlockXPBottler.java:32-41) |
| 经验收集器 | Material.glass(BlockXPDrain.java:12) |
高度仅 1/16 的平板 setBlockBounds(0,0,0,1,0.0625,1)(:13),FOUR_DIRECTIONS,非实心(:21-23) |
由 OpenBlock 基类决定 |
| 喷经验浴 | Material.rock(BlockXPShower.java:20) |
FOUR_DIRECTIONS + SURFACE 放置 + TESR_ONLY 渲染(:21-23),非实心(:26-28) |
细柱模型,方块边界按朝向旋转(:48-60) |
| 自动铁砧 | Material.anvil(BlockAutoAnvil.java:14) |
setStepSound(soundTypeAnvil) + TWO_DIRECTIONS + TESR_ONLY(:15-17),非实心且各面均不实(:25-31) |
由 OpenBlock 基类决定 |
| 自动附魔台 | Material.rock(BlockAutoEnchantmentTable.java:20) |
高度 0.75,RenderMode.BOTH(:21-22),非实心(:23-25) |
顶/底 openblocks:autoenchantmenttable_top / _bottom(:70-71) |
功能
XP 瓶机(TileEntityXPBottler)
2 格物品容器 + 1 个液体罐,把经验液重新装入玻璃瓶,产出原版附魔之瓶。
- 罐容量
TANK_CAPACITY = xpToLiquidRatio(XP_PER_BOTTLE)= 8 × 20 = 160 mB(TileEntityXPBottler.java:51、LiquidXpUtils.java:8、:15) - 工作周期
PROGRESS_TICKS = 40(2 秒)(TileEntityXPBottler.java:52) - 开工条件
hasSpaceInOutput() && hasGlassInInput() && isTankFull()(:148)。isTankFull()判断的是恰好等于容量(:220-222),不是「至少」 - 完成后消耗 1 个玻璃瓶、清空罐、产出 1 个
Items.experience_bottle,播放openblocks:bottler.signal(:150-173) - 输入槽只接受
Items.glass_bottle(:72-75) - 不能排出液体:
canDrain恒返回 false(:229-232),即经验液只能进不能出 - 3 个可配置自动槽(
AutoSlots枚举,:57-61):input— 每刻从选定侧面拉 1 个玻璃瓶(:140-146)output— 每刻向选定侧面推出 1 个成品(:130-136)xp— 每刻从选定侧面灌入 10 mB 经验液(:118-125)
IFluidHandler实现是SidedFluidHandler.Drain(:93)——只有 Drain 能力
经验收集器(TileEntityXPDrain)
1 格薄板,放置在液体罐正上方。每 100 刻向下搜索一次目标罐(TileEntityXPDrain.java:28-30、:96-112):从 yCoord - 1 向下逐格,遇到第一个实现了 IFluidHandler 的 TileEntity 即锁定;遇到非 FluidHandler 但不透明的方块则中止(searchForTank,:95-111)。目标以 WeakReference 持有,每刻校验(:32-36)。
工作分两条:
| 目标 | 范围 | 行为 | 单次上限 |
|---|---|---|---|
经验球 EntityXPOrb |
本格 y .. y+0.3(:130-134) |
整球转换;只有罐子能全部装下才吃球(tryConsumeOrb,:83-94) |
球的全部 XP |
玩家 EntityPlayer |
本格 y .. y+1(:123-127) |
抽玩家经验 | 每刻最多 4 点(tryDrainPlayer,:54) |
玩家抽经验时先 tank.fill(..., false) 试填,再经 liquidToXpRatio 向下取整后二次填充(:59-68),最后扣玩家经验(:80)。每 4 刻播放一次 random.orb 音效(:70-77)。
tryDrainPlayer只处理经验值> 0的玩家(:51-52),因此死亡后经验为 0 的玩家不会被抽取。
喷经验浴(TileEntityXPShower)
3 刻一次的脉冲,把经验液转成不会飞走的经验球(EntityXPOrbNoFly)。
- 缓冲罐容量
FluidContainerRegistry.BUCKET_VOLUME(1000 mB)(TileEntityXPShower.java:24-26) - 每 3 刻从北面灌入
DRAIN_PER_CYCLE = 50mB(:21、:50) - 液体转 XP 后按
EntityXPOrb.getXPSplit拆成多个球,逐个生成(:55-70) - 红石反相:
isOn = !isBlockIndirectlyGettingPowered(...)(updateState,:102-105)——有红石信号时关闭。onAdded与onNeighbourChanged都会刷新状态(:89-99) - 客户端仅在
particleLevel允许时喷粒子,且粒子喷吐有 10 刻的滞后计时(:78-99)
自动铁砧 / 自动附魔台
自动铁砧为 TESR_ONLY 渲染,材质是 Material.anvil。自动附魔台保留了原版附魔台的 randomDisplayTick 飘字粒子(BlockAutoEnchantmentTable.java:29-57),并单独注册顶/底贴图。两者的完整加工与过滤槽逻辑分别在 TileEntityAutoAnvil 与 TileEntityAutoEnchantmentTable 中——本次未逐行核对这两个 TE,故其具体过滤行为按模组 API 与扩展点所述的 GUI 框架处理,此处不做数值断言。
数值
| 数值名 | 来源 | 值 |
|---|---|---|
| 每瓶经验 | LiquidXpUtils.XP_PER_BOTTLE |
8(LiquidXpUtils.java:8) |
| 液体↔XP 比值 | Config.xpToLiquidRatio |
20 mB / 点(Config.java:539) |
| 瓶机罐容量 | xpToLiquidRatio(8) |
160 mB(TileEntityXPBottler.java:51) |
| 瓶机周期 | PROGRESS_TICKS |
40 刻(TileEntityXPBottler.java:52) |
| 瓶机自动灌液速率 | 硬编码 | 10 mB / 刻(TileEntityXPBottler.java:109) |
| 经验收集器抽玩家速率 | 硬编码 | ≤ 4 点 / 刻(TileEntityXPDrain.java:54) |
| 经验收集器搜索间隔 | 硬编码 | 100 刻(TileEntityXPDrain.java:29) |
| 喷经验浴脉冲间隔 | 硬编码 | 3 刻(TileEntityXPShower.java:46) |
| 喷经验浴单次灌液量 | DRAIN_PER_CYCLE |
50 mB(TileEntityXPShower.java:21) |
| 喷经验浴缓冲罐 | BUCKET_VOLUME |
1000 mB(TileEntityXPShower.java:25) |
LiquidXpUtils 的三个换算函数(LiquidXpUtils.java:10-20):
liquidToXpRatio(liquid)=liquid / xpToLiquidRatio(整除,向下取整)xpToLiquidRatio(xp)=xp * xpToLiquidRatiogetLiquidForLevel(level)= 先EnchantmentUtils.getExperienceForLevel(level)再乘系数
因 liquidToXpRatio 整除,1 瓶(8 点 = 160 mB)恰好整除;但任意非 20 倍数的液体会被静默丢弃。
交互
| 触发 | 行为 |
|---|---|
| XP 瓶机工作完成 | 播放 openblocks:bottler.signal(TileEntityXPBottler.java:151-157) |
| 经验收集器每 4 刻 | 播放 random.orb,音高随机(TileEntityXPDrain.java:66-73) |
| 经验收集器下方罐子被移除 | WeakReference 失效,下一个 100 刻周期重新搜索(TileEntityXPDrain.java:32-36) |
| 喷经验浴通电 | 关闭喷球(红石反相,TileEntityXPShower.java:98-101) |
| 喷经验浴相邻方块变化 | 重新计算开关状态(TileEntityXPShower.java:90-93) |
合成配方
XP 瓶机(Config.java:828-840):
ng
NgN
ng
| 字符 | 物品 |
|---|---|
n |
netherrack 下界岩 |
g |
blockGlass 玻璃 |
经验收集器(Config.java:888-892):
n
nnn
n
| 字符 | 物品 |
|---|---|
n |
netherrack 下界岩 |
自动铁砧(Config.java:860-871):
iii
iAi
iii
| 字符 | 物品 |
|---|---|
i |
ingotIron 铁锭 |
A |
Blocks.anvil 铁砧 |
自动附魔台(Config.java:874-886):
ddd
dEd
ddd
| 字符 | 物品 |
|---|---|
d |
blockDiamond 钻石块 |
E |
Blocks.enchanting_table 附魔台 |
喷经验浴(Config.java:1090-1102):
ow
ono
wo
| 字符 | 物品 |
|---|---|
o |
Blocks.obsidian 黑曜石 |
w |
Blocks.water_bucket 水桶 |
n |
netherrack 下界岩 |
相关条目
- 配置项全表 -
xpToLiquidRatio与其它 91 个配置项 - 物品 / 地图与制图物品 -
OpenBlocks:xpbucket装的是同一种液体 - 喷洒器与水车 - 液体供给的另一种方案