Drawbridge 放置规则

核心结论:137 条白名单是死数据

lib/TMechworksRegistry.java 用 137 次 drawbridgeState.put(...) 建立了一张 ItemStack → PlacementType 的放置白名单。但它在运行时从未被读取。

全仓对 drawbridgeState 的引用只有 3 处:

位置 状态
lib/TMechworksRegistry.java:39 public static HashMap<ItemStack, PlacementType> drawbridgeState = ... —— 声明
blocks/logic/DrawbridgeLogic.java:478 在 validMetadata 内的 /** ... */ 注释块中
blocks/logic/AdvancedDrawbridgeLogic.java:502 同上

两个 validMetadata 实现的真实函数体都是一行:

boolean validMetadata(Block block, int metadata) {
    /**
     * int type = TMechworksRegistry.drawbridgeState.get(block).getTypeID();
     * if (type == 0) { return metadata == bufferStack.getItemDamage(); }
     * if (type == 1) { return true; }
     * if (type == 2) { return false; }        // ← GTFO 会被这里挡住
     * if (type == 3) { return true; // TODO: rotational metadata, probably not needed anymore }
     * if (type == 4) { return true; }
     * if (type == 5) { return metadata == bufferStack.getItemDamage(); }
     */
    return true;
}

(blocks/logic/DrawbridgeLogic.java:476-483;Advanced 版同构,:500-508)

因此当前的实际放置规则(DrawbridgeLogic.updateEntity 判定链,:396-400)是:

if (bufferStack != null && validBlock(block) && validMetadata(block, meta)   // 恒 true
        && validDrawbridge(xPos, yPos, zPos) && !hasInventory(xPos, yPos, zPos))

外加 isItemValidForSlot(slot, itemstack)(:580-596)的 3 条检查:必须是 ItemBlock、槽 1 额外要求 isOpaqueCube() && renderAsNormalBlock() 且堆叠 1、不在配置黑名单中。

即:Drawbridge 可以放任何非黑名单的方块物品,包括 metadata 5–7 的 137 个 GTFO 方块(bedrock / 下界传送门 / 刷怪笼 / 石门 / 仙人掌 …)。

7 种 PlacementType

lib/blocks/PlacementType.java:

常量 typeID 语义(源码注释) 注册条数
metaMatch 0 Metadata has to match 0
metaIgnore 1 Metadata has no meaning 86
GTFO 2 Should not be placed 17
rotationalMeta 3 Has rotational metadata 27
rails 4 Rails 4
rotationalTE 5 Has rotational TileEntity data 3
custom 6 Custom placement logic 0
合计 137

metaMatch 与 custom 的 grep 命中各 1 次,但都在文件头的注释块中(lib/TMechworksRegistry.java:67 与 :70),不是真实注册。这两个枚举常量是纯死代码 —— 尤其 custom 意味着没有任何方块走自定义放置路径。

GTFO(17 个)—— 名义上会被烧掉,实际可放

bedrock        bed             piston_extension  mob_spawner    wheat
wooden_door    iron_door       cactus           portal         cake
pumpkin_stem   melon_stem      nether_wart      end_portal     cocoa
carrots        skull

注释与原始意图在 lib/TMechworksRegistry.java:130-152(如 // Bedrock, not sure why its in the list to be honestly truthful.)。当前这些方块均可被 Drawbridge 正常放置,包括下界传送门(portal)与末地传送门(end_portal)—— 后两者由游戏自身在 onBlockPlaced 中拒绝,故实际不会真的生成。

rails(4 个)

golden_rail   detector_rail   rail   activator_rail

rotationalTE(3 个)

chest   ender_chest   trapped_chest

唯一需要「同时旋转方块 metadata 与 TE 内朝向 NBT」的类型。当前该逻辑同样被注释掉,箱子会被按原始朝向放置。

Tinkers’ Construct 方块

仅 2 个进入白名单(lib/TMechworksRegistry.java:226-227):

drawbridgeState.put(new ItemStack(TinkerWorld.slimePad),    PlacementType.metaIgnore);
drawbridgeState.put(new ItemStack(TinkerWorld.bloodChannel), PlacementType.metaIgnore);

没有任何 TCon 金属锭、工具部件或矿物进入白名单。TCon 资源在本 mod 的其他用途:Dynamo 的贴图、[过滤网类型](../setting/filter-types) 的 ToolCore/ToolPart 判据、各配方的 ingotAluminumBrass 等材料。

实际生效的映射表

drawbridgeState 之外,以下 3 张表确实在运行时被使用:

映射 条数 运行时调用点 用途
blockToItemMapping 5 DrawbridgeLogic.java:291 HashBiMap,双向「方块 ↔ 物品」:redstone_ore↔redstone、redstone_torch↔unlit_redstone_torch、unpowered_repeater↔repeater、unpowered_comparator↔comparator、grass↔dirt
interchangableBlockMapping 9 DrawbridgeLogic.java:314-318 单向替换:redstone_ore→lit_redstone_ore、redstone_torch→lit_redstone_torch、powered_repeater→powered_repeater 等
drawbridgeBlackList 配置驱动 DrawbridgeLogic.java:591 isItemDBBlacklisted(ItemBlock),由 配置文件 的 drawbridge.blacklist 填充

drawbridgeBlackList 是 private static List<ItemBlock>,支持 modid:blockname 语法(无冒号则默认 minecraft),并提供 addItemToDBBlackList(Item) / addItemToDBBlackList(Block) 两个运行时 API。

数值

数值 值
drawbridgeState 条数 137(全部死数据)
metaIgnore / rotationalMeta / GTFO / rails / rotationalTE 86 / 27 / 17 / 4 / 3
metaMatch / custom 0 / 0
validMetadata 实际逻辑 恒 return true(两个实现)
blockToItemMapping 5(HashBiMap,双向)
interchangableBlockMapping 9(单向为主)
drawbridgeBlackList List<ItemBlock>,配置 + 2 个 API
isItemValidForSlot 条件 instanceof ItemBlock + 非黑名单(槽 1 额外要求 isOpaqueCube && renderAsNormalBlock 且堆叠 1)
TCon 方块 2(slimePad、bloodChannel)
表键类型 HashMap<ItemStack, PlacementType>(含 metadata 比较)

源码缺陷

  • 137 条白名单全部是死数据(见上文)—— 本条目最重要的一条。validMetadata 的注释块里保留了完整的 6 分支逻辑与 // TODO: rotational metadata, probably not needed anymore 的待办,说明这是主动放弃而非忘记,但 GTFO 的 17 个方块因此失去保护。
  • 注释掉的代码块被保留在函数体内(DrawbridgeLogic.java:477-482):两处共 12 行注释代码留在源文件里,读者容易误以为逻辑生效。Advanced 版同样 8 行。
  • interchangableBlockMapping 9 条中 7 组只注册一个方向:只有 dirt ↔ grass 双向(:222-223)。redstone_ore、redstone_torch、unpowered_repeater、powered_repeater、unpowered_comparator、powered_comparator 均单向。放置时若映射查不到会 return(不放置),故「用 lit_redstone_ore 反向放置」不可用。
  • Blocks.tripwire_hook 被 put 两次(:191-192),第二次覆盖第一次 —— 复制粘贴残留。
  • 两张表键类型不一致:drawbridgeState 键是 ItemStack(含 metadata),另两张是 Block(HashBiMap/HashMap),updateEntity 需 Item.getIdFromItem 桥接(:291),类型转换链冗长。
  • addItemToDBBlackList(Block) 名为 addItem 实收 Block(:289),且抛 RuntimeException 而非 IllegalArgumentException。
  • 无效方块名只 warn 不 fail(:256):"Invaild block: " + blockNameCompond —— 源码里 Invaild 是拼写错误。
  • TMechworksRegistry 的 static {} 与配置读取的顺序依赖:TMechworks.preInit 先 ConfigCore.loadConfig()(:52)再首次引用 TMechworksRegistry(:54,new TabTools)。顺序恰好正确但无注释保护,重构时极易破坏。
  • drawbridgeState 若被重新启用会立即出问题:它以 ItemStack 为键而所有 put 用 new ItemStack(block)(damage 0),只覆盖 meta 0。玩家持有 minecraft:log meta 15 时查不到 → 无法放置。这是恢复该功能前必须先修的坑。

相关条目