工具模式
基本信息
| 属性 | 值 |
|---|---|
| 枚举类 | com.github.lunatrius.schematica.tool.ToolMode(7 个常量,tool/ToolMode.java:23-29) |
| 状态持有 | com.github.lunatrius.schematica.tool.ToolManager.currentMode |
| 默认模式 | ToolMode.SCHEMATIC_PLACEMENT(tool/ToolManager.java:24) |
| 来源 | 从 Litematica 的 ToolMode 移植(tool/ToolMode.java:19 作者署名 HackerRouter / masa) |
每个模式持有 5 个特征位(tool/ToolMode.java:23-29 的构造器实参顺序):translationKey / creativeOnly / usesSchematic / usesBlockPrimary / usesBlockSecondary。
getUsesAreaSelection() 不是独立字段,而是 !usesSchematic 的派生值(:64-66)。
功能
工具系统把手持配置物品(config.toolItem,默认 minecraft:stick)时的左键 / 右键 / Execute 键分派到 7 种模式之一。ToolManager.isHoldingToolItem()(tool/ToolManager.java:32-48)先比对 held.getItem() != ConfigurationHandler.toolItemType,再在 toolItemMeta >= 0 时比对 meta(:41-46)。
数值
| 模式 | 翻译键 | 仅创造 | 需蓝图 | 主方块 | 目标方块 | 需区域选择 |
|---|---|---|---|---|---|---|
AREA_SELECTION |
schematica.tool_mode.area_selection |
否 | 否 | 否 | 否 | 是 |
SCHEMATIC_PLACEMENT |
schematica.tool_mode.schematic_placement |
否 | 是 | 否 | 否 | 否 |
PASTE_SCHEMATIC |
schematica.tool_mode.paste_schematic |
是 | 是 | 否 | 否 | 否 |
MOVE |
schematica.tool_mode.move |
否 | 是 | 否 | 否 | 否 |
DELETE |
schematica.tool_mode.delete |
是 | 否 | 否 | 否 | 是 |
FILL |
schematica.tool_mode.fill |
是 | 否 | 是 | 否 | 是 |
REPLACE_BLOCK |
schematica.tool_mode.replace_block |
是 | 否 | 是 | 是 | 是 |
「需区域选择」列 = !usesSchematic(tool/ToolMode.java:64-66)。
7 个模式中 4 个标记为仅创造(PASTE_SCHEMATIC、DELETE、FILL、REPLACE_BLOCK),生存模式下 cycle 会跳过它们(:125-147)。
中文显示名见 assets/schematica/lang/zh_CN.lang:151-157:区域选择 / 投影放置 / 粘贴投影 / 移动 / 删除 / 填充 / 替换方块。
交互
模式切换
ToolMode.cycle(boolean forward)(tool/ToolMode.java:125-147)从当前 ordinal 出发按 ±1 环形推进,跳过 creativeOnly 且玩家不在创造模式时的模式(:140)。若所有候选都被跳过则返回原模式(:146)。
调用方唯一入口是 ToolManager.cycleMode(boolean)(tool/ToolManager.java:71-74),由 ToolItemHandler 的 Ctrl+滚轮触发,方向为 dwheel < 0(向下滚 = 下一个)→ 见 键位。
模式切换没有独立键位——InputHandler.KEY_BINDINGS 的 5 个键位中没有模式循环项(handler/client/InputHandler.java:54-56)。
射线选取距离
SCHEMATIC_PLACEMENT、MOVE 以及所有需区域选择的模式走长距离射线,PLACEMENT_RAYCAST_DISTANCE = 256.0(tool/ToolManager.java:77),从玩家眼位到 eyePos + look * 256 调 worldObj.rayTraceBlocks(:104-117),仅返回 typeOfHit == BLOCK 的命中(:113)。其他模式优先用 ClientProxy.movingObjectPosition,为 null 时才回退到长距离射线(:90-94、:129-133)。
各模式实际行为
ToolHandler(tool/ToolHandler.java)按「左键 / 右键 / Execute」三条路径分派:
| 模式 | 左键(attack) | 右键(use) | Execute |
|---|---|---|---|
AREA_SELECTION |
设 point A(:207-212) |
设 point B(:197-202) |
打开 GuiSchematicSave(:217-220) |
SCHEMATIC_PLACEMENT |
无(:108-116 落 default) |
打开 GuiSchematicLoad 载入蓝图(:229-239) |
无(onExecute default,:152-153) |
PASTE_SCHEMATIC |
无 | 无(:66-68 显式返回 false) |
粘贴蓝图(:132-138) |
MOVE |
无 | 蓝图原点移到目标方块正上方,无目标则移到玩家(:247-262) |
无 |
DELETE |
无 | 无 | 删除选区内方块(:481-505) |
FILL |
拾取主方块(:104-106) |
无 | 用主方块填充选区(:544-580) |
REPLACE_BLOCK |
拾取主方块 | 拾取目标方块(:61-63) |
用主方块替换目标方块(:615-659) |
设点后统一调 ClientProxy.updatePoints() 并把 isRenderingGuide 置 true(:200-201、:210-211)。
方块拾取
pickBlockFromCrosshair(tool/ToolHandler.java:165-190)从 player.worldObj 读准星下方方块与 meta,拒绝空气(:176-179),存入当前模式的 primaryBlock / secondaryBlock。
也可通过客户端指令 /sblock 直接设置,见 指令。
Execute 的两种执行路径
PASTE_SCHEMATIC / DELETE / FILL / REPLACE_BLOCK 都先检查 player.capabilities.isCreativeMode(),非创造模式直接回 "Paste/Delete/Fill/Replace requires creative mode."(:269-272、:482-485、:545-548、:616-619)。
四个模式都先检查选区是否有效——若 pointMin 与 pointMax 三轴全等则回 "No area selected. Use Area Selection mode first."(:490-493、:553-556、:624-627)。
拿到 WorldServer 时走 ExtendedBlockStorage 直写(pasteDirectly :316-423、deleteDirectly :508-521、fillDirectly :582-594、replaceDirectly :661-676);拿不到时降级为向聊天框逐条发送 /setblock 与 /summon(pasteWithSetblock :428-477、deleteWithSetblock :523-540、fillWithSetblock :596-611、replaceWithSetblock :678-696)。
⚠️ 降级路径调用的是 clientPlayer.sendChatMessage(cmd)(如 :451、:468、:533、:605、:689),即把指令以聊天消息发出,只有在服务端允许玩家执行 /setblock 与 /summon 时才生效。
PASTE_SCHEMATIC 的直写路径刻意完全绕过 onBlockAdded / onNeighborBlockChanged 回调(:321-324 注释与 :337-350 的 ExtendedBlockStorage.func_150818_a 直写),以避免门等脆弱多方块在邻接检查不全时崩坏;随后单独第三遍循环用 markBlockForUpdate 通知客户端渲染(:404-420)。
实体粘贴前会移除 UUIDMost / UUIDLeast(:390-391)让 EntityList.createEntityFromNBT 重新分配 UUID(:393)。实体粘贴受 schematic.isRenderingEntities 开关控制(:378),TileEntity NBT 粘贴受 schematic.isPastingBlockNBT 开关控制(:355)。
数值
| 数值名 | 值 | 来源 |
|---|---|---|
| 模式数量 | 7 | tool/ToolMode.java:23-29 |
| 仅创造模式数 | 4 | tool/ToolMode.java:25,27,28,29 |
| 射线最大距离 | 256.0 | tool/ToolManager.java:77 |
| 翻译键数量 | 7 | assets/schematica/lang/en_US.lang:151-157 |