Horizon Wand
基本信息
| 属性 | 值 |
|---|---|
| 注册名 | horizonqa:wand |
| 实现类 | com.gtnewhorizons.horizonqa.item.ItemHorizonWand |
| 注册代码 | CommonProxy.java:78-79(GameRegistry.registerItem(ItemHorizonWand.INSTANCE, "wand")) |
| 内部名 | horizonqa.wand(ItemHorizonWand.java:53) |
| 显示名 | Horizon Wand(en_US.lang:1) |
| 材质 | minecraft:blaze_rod(复用烈焰棒,ItemHorizonWand.java:54) |
| 最大堆叠 | 1(ItemHorizonWand.java:55) |
| 创造标签 | CreativeTabs.tabTools(ItemHorizonWand.java:56) |
| TileEntity | 无 |
| 合成配方 | 无(全仓库无该物品的配方注册) |
[!NOTE] Horizon-WA 是 Horizon-QA 注册的唯一物品,也是唯一注册的游戏内容物品。
grep -rn 'GameRegistry.registerItem' src/main/java只有CommonProxy.java:79一处命中; 0 个方块、0 个 TileEntity、0 个实体、0 个合成配方。
功能
Horizon Wand 是结构模板编辑工具:玩家用它框选一个长方体选区(Pos1 / Pos2),
在选区内的具体方块坐标上打命名标签,再把整个选区导出为可被 @GameTest 复用的结构模板。
选区操作
- 左键方块(
onItemUse):若当前没有pending标记则设 Pos1,否则设 Pos2(ItemHorizonWand.java:59-77) - 右键空气(
onItemRightClick):用视线射线命中的方块位置按同样的 pending 逻辑设点(ItemHorizonWand.java:79-91) - 潜行(Shift)时点击方块表面:坐标沿命中面法线外推一格(
FACE_NORMALS表,ItemHorizonWand.java:47-49、64-68) - 设定 Pos1 会清空 Pos2 标记、标签与导出名(
ItemHorizonWand.java:152-156) - 视线未命中方块时,取交互距离末端的整数坐标(
ItemHorizonWand.java:126-129) - 交互距离取自
EntityPlayerMP.theItemInWorldManager.getBlockReachDistance(),非 MP 玩家回退 5.0(ItemHorizonWand.java:132-140)
标签系统
标签是"名字 → 绝对方块坐标"的映射,存于 NBT 的 labels 复合标签下,按名字排序(TreeMap,
ItemHorizonWand.java:234-253)。测试代码用 helper.pos("名字") 解析为 TestPos。
- 名字合法性:
StructureAnnotations.isValidLabelName(ItemHorizonWand.java:226-228),语言文件给出的规则为[A-Za-z_][A-Za-z0-9_]*(en_US.lang:31) - 同名标签若已存在于另一坐标,返回
DUPLICATE_NAME并拒绝写入(ItemHorizonWand.java:280-282) - 同一坐标上的旧名字会被新名字顶替(
ItemHorizonWand.java:288-290) moveLabel每次沿单轴移动一格,且不允许与其他标签落在同一格(ItemHorizonWand.java:324-362)- 坐标边界:X/Z 为 ±30,000,000,Y 为 0–255(
ItemHorizonWand.java:339-340)
选区整体变换
moveSelection:整个选区与全部标签沿单轴平移一格(ItemHorizonWand.java:384-429)resizeSelection:单轴向外/向内扩缩一格,不移动标签;缩到 1 格以下会失败(ItemHorizonWand.java:438-452)
这两个变换是 Horizon Editor(客户端自由相机)拖拽手柄时调用的服务端同步入口,
经由 WandSelectionMoveMessage / WandSelectionResizeMessage 两个封包下发
(HorizonQANetwork.java:16-24)。
物品提示
addInformation(客户端)按 NBT 状态显示 Pos1/Pos2 坐标、选区尺寸与三个操作提示
(ItemHorizonWand.java:176-217):Shift 表面模式、标签键、自由相机键。
数值
| 数值名 | 值 | 来源 |
|---|---|---|
| 最大堆叠 | 1 | ItemHorizonWand.java:55 |
| 标签名合法字符 | [A-Za-z_][A-Za-z0-9_]* |
en_US.lang:31 |
| 坐标范围 X / Z | −30,000,000 ~ 30,000,000 | ItemHorizonWand.java:339-340 |
| 坐标范围 Y | 0 ~ 255 | ItemHorizonWand.java:339-340 |
| 非 MP 玩家默认交互距离 | 5.0 | ItemHorizonWand.java:139 |
| 标签键默认按键 | L |
WandLabelInput.java:19-21 |
| 自由相机键默认按键 | F10 |
WandFreecamController.java:55-57 |
NBT 标签键
| NBT 键 | 类型 | 含义 | 来源 |
|---|---|---|---|
pos1X / pos1Y / pos1Z |
int | 选区第一角 | ItemHorizonWand.java:32-34 |
pos1Set |
boolean | 第一角是否已设 | ItemHorizonWand.java:35 |
pos2X / pos2Y / pos2Z |
int | 选区对角 | ItemHorizonWand.java:36-38 |
pos2Set |
boolean | 对角是否已设 | ItemHorizonWand.java:39 |
pending |
boolean | 是否等待设置 Pos2 | ItemHorizonWand.java:40 |
labels |
compound | 名字 → {x,y,z} |
ItemHorizonWand.java:41 |
exportName |
string | 记住的导出名 | ItemHorizonWand.java:42 |
交互
| 触发 | 行为 |
|---|---|
| 左键方块 | 设 Pos1(无 pending 时)或 Pos2 |
| 右键空气 | 按视线命中位置设 Pos1 / Pos2 |
| 潜行 + 点击方块表面 | 坐标沿面法线外推一格(表面模式) |
按 L |
打开标签输入框,给当前瞄准坐标打标签(仅手持 Wand、无 GUI、自由相机未开) |
按 F10 |
开/关 Horizon Editor 自由相机编辑器 |
/horizonqa clear |
清空整个 Wand 的 NBT(HorizonQACommand.java:983-999) |
/horizonqa export |
需要 Pos1 与 Pos2 都已设置,否则拒绝并提示(HorizonQACommand.java:783-790) |
[!WARNING] 客户端渲染(标签渲染、HUD、自由相机)只在
interactive模式注册:ClientProxy.init在interactiveFeaturesEnabled()为假时直接 return(ClientProxy.java:21-22)。
相关条目
- /horizonqa 指令 -
load/export/label/labels/clear均需要手持或背包内有 Wand - JVM 系统属性 - 客户端功能由
-Dhorizonqa.mode=interactive门控 - Horizon Editor - 自由相机与选区变换面板