跳到正文
烈焰甘蔗Wiki

放置范围客户端预览

魔杖瞄准方块时,客户端会用白色线框把即将放置的所有方块画出来。 这是 core/BlockEvents.java 在 DrawBlockHighlightEvent 中实现的。

基本信息

属性 值
类 portablejim.bbw.core.BlockEvents
注册 ClientProxy.RegisterEvents() → MinecraftForge.EVENT_BUS.register(blockEvents)
事件 DrawBlockHighlightEvent(仅客户端存在)
渲染 API 纯 OpenGL 立即模式(LWJGL GL11)

⚠️ 该类只在客户端加载(由 ClientProxy 实例化)。 服务端的 ServerProxy 继承 CommonProxy,RegisterEvents() 是空实现, 因此服务端不做任何预览计算,也省掉了 BFS 的开销。

触发条件

三个条件必须同时满足才画预览:

if (event.currentItem != null && event.currentItem.getItem() instanceof IWandItem
        && event.target != null
        && event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
条件 说明
手持物品是 IWandItem 即本 mod 的四根魔杖之一
准星命中方块 不能命中实体或空气
sourceItems instanceof ItemBlock 目标方块有对应的物品形式

第三个条件在源码里检查了两次(外层 IWandItem 判断 + 内层重复判断), 属于冗余但无害的代码。

计算流程:与服务端完全一致

预览调用的是与服务端 onItemUse 同一套方法:

步骤 方法
① 取材料 worker.getProperItemStack(worldShim, playerShim, clickedPos)
② 查映射 mappingManager.getMapping(targetedBlock, meta)
③ 算上限 Math.min(wand.getMaxBlocks(...), playerShim.countItems(...))
④ BFS worker.getBlockPositionList(...)

唯一差异:预览走 mappingManager.getMapping(block, meta), 而服务端 ItemBasicWand.getCustomMapping() 额外支持 Backhand 副手分支。 装了 Backhand 且副手持方块时,预览和实际放置的目标可能不一致。

countItems 里会走 AE2 的客户端分支(见 网络协议), 所以预览的上限也受 AE2 数量同步的 10 刻延迟影响。

渲染参数

GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glDepthMask(true);
GL11.glLineWidth(2.5F);
for (Point3d block : blocks) {
    AxisAlignedBB boundingBox = AxisAlignedBB
            .getBoundingBox(x, y, z, x + 1, y + 1, z + 1)
            .contract(0.005, 0.005, 0.005);
    RenderGlobal.drawOutlinedBoundingBox(boundingBox.getOffsetBoundingBox(-interpolatedX, …), 0xC0C0C0);
}
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
参数 值 作用
线宽 2.5F 比默认线更粗,远距离也看得清
颜色 0xC0C0C0 银灰
AABB 收缩 每轴 0.005 避免相邻格线框重叠成实心块
深度写入 glDepthMask(true) 被实体遮挡的方块也能看到线框
混合 GL_BLEND 开启/结束时关闭 半透明叠加

坐标做了插值平滑,避免跟随玩家时抖动:

double interpolatedX = event.player.lastTickPosX + (event.player.posX - event.player.lastTickPosX) * event.partialTicks;

绘制完会把 GL_TEXTURE_2D 和 GL_BLEND 状态还原,不污染其他渲染器。

边界情况

情况 表现
BFS 结果为空(种子被面锁定拒绝) 不画任何线框(if (!blocks.isEmpty()))
目标方块在硬黑名单里 getProperItemStack 返回 null → 不画
材料数量为 0 countItems 返回 0 → maxBlocks = 0 → BFS 立刻退出 → 不画
创造模式 CreativePlayerShim.countItems 恒 MAX_VALUE → 画出魔杖理论上限

⚠️ 创造模式预览会画出满上限范围(如 Unbreakable Wand 的 4096 格), 因为创造模式不扣材料也不扣耐久。

相关条目

浏览全部模组