Baubles Expanded 兼容
基本信息
| 属性 | 值 |
|---|---|
| 目标 modid | Baubles|Expanded(带竖线) |
| 门控位置 | mixins/Mixins.java:53 .addRequiredMod(TargetedMod.BAUBLES_EXPANDED) |
| 枚举定义 | mixins/TargetedMod.java:10 BAUBLES_EXPANDED("Baubles|Expanded") |
| 运行时检测 | WitcheryExtras.java:63 Loader.isModLoaded("Baubles|Expanded") |
| 编译依赖 | compileOnly('com.github.GTNewHorizons:Baubles-Expanded:2.2.22-GTNH:dev')(dependencies.gradle) |
| 涉及的 Mixin | 3 个 |
✅ Baubles Expanded 在本 wiki 收录范围内(分类
baubles-expanded), 跨分类链接见 分类页。 相对地,Witchery 本体不在收录范围(见 分类页)。
⚠️ modid 陷阱
Baubles|Expanded 是 GTNH 版 Baubles-Expanded 的父 modid,
不是 Baubles,也不是 BaublesExpanded。
| 字符串 | 出现在 | 含义 |
|---|---|---|
Baubles|Expanded |
TargetedMod.java:10、WitcheryExtras.java:63 |
父 modid,本 mod 门控用的就是它 |
Baubles |
—— | 主 mod 自己的 modid(见 baubles-expanded 分类页) |
本 mod 里没有出现 Baubles 这个字符串——若哪天看到 Loader.isModLoaded("Baubles")
就说明门控写错了。
preInit 阶段的槽位申请
if (Loader.isModLoaded("Baubles|Expanded")) {
BaubleExpandedSlots.tryAssignSlotsUpToMinimum(BaubleExpandedSlots.beltType, 1);
BaubleExpandedSlots.tryAssignSlotsUpToMinimum(BaubleExpandedSlots.charmType, 1);
}
(WitcheryExtras.java:63-66)
在 preInit 里申请腰带(belt)与挂饰(charm)各至少 1 个槽位。
用 tryAssignSlotsUpToMinimum(类型, 1)——只保证至少 1 个,
具体分配到哪几个槽由 Baubles Expanded 决定。
3 个 Mixin
1. BlockWitchDoorMixin_Bauble —— 女巫门钥匙
@WrapMethod 包住 hasKeyForDoor(BlockWitchDoorMixin_Bauble.java:23-26),
让挂在饰品栏里的门钥匙也能开女巫门。
关键实现(BlockWitchDoorMixin_Bauble.java:28-45):
// func_150012_g == getFullMetadata with MCP mappings. We use it to get the Y coord of the bottom door block,
// which has the NBT data we want, even if the player clicks on the top block.
final int doorBaseY = (((BlockWitchDoor) (Object) this).func_150012_g(world, x, y, z) & 8) == 0 ? y : y - 1;
IInventory baubles = BaublesApi.getBaubles(player);
for (int slot = 0; slot < baubles.getSizeInventory(); slot++) {
ItemStack bauble = baubles.getStackInSlot(slot);
if (Witchery.Items.GENERIC.itemDoorKey.isMatch(bauble)) {
if (witcheryExtras$keyNBTMatchesDoor(bauble.getTagCompound(), x, doorBaseY, z, world.provider.dimensionId))
return true;
continue;
}
...
}
- 用
func_150012_g(getFullMetadata)的& 8位判断点击的是上半还是下半门, 换成下半门的 Y 坐标——注释明确说明「即使玩家点的是上半门」 - 匹配条件是
witcheryExtras$keyNBTMatchesDoor(baubleNBT, x, doorBaseY, z, dimensionId)——钥匙 NBT 里绑定的坐标与维度必须完全一致
2. ItemGeneralMixin_Bauble —— 罗温钥匙 / 钥匙串
ItemGeneral(Witchery 的通用物品容器类)通过 implements IBaubleExpanded(ItemGeneralMixin_Bauble.java:29)
让其中 2 个子物品成为饰品:
@Unique
private static final String[] witcheryExtras$rowanKeyBaubleTypes = { BaubleExpandedSlots.amuletType,
BaubleExpandedSlots.beltType, BaubleExpandedSlots.charmType };
(ItemGeneralMixin_Bauble.java:32-33)
匹配的 2 个子物品(通过 @Final @Shadow 取用,ItemGeneralMixin_Bauble.java:37-40):
| 字段 | 物品 |
|---|---|
itemDoorKey |
罗温钥匙 |
itemDoorKeyring |
钥匙串 |
可用槽位类型:护符(amulet)、腰带(belt)、挂饰(charm)。
| 补丁 | 行 | 作用 |
|---|---|---|
@Inject addInformation(TAIL,仅客户端) |
ItemGeneralMixin_Bauble.java:45-52 |
BaubleItemHelper.addSlotInformation(tooltip, 类型数组),tooltip 追加可用的饰品槽类型 |
@WrapMethod onItemRightClick |
ItemGeneralMixin_Bauble.java:53-58 |
右键时走 BaubleItemHelper.onBaubleRightClick(stack, world, player) 装到饰品栏;不匹配则 original.call(...) 走原版逻辑 |
getBaubleTypes(ItemStack) |
ItemGeneralMixin_Bauble.java:62-64 |
匹配则返回 3 个槽类型,否则返回 null |
getBaubleType(ItemStack) |
ItemGeneralMixin_Bauble.java:66-68 |
直接 return null(该接口方法未实现) |
3. ItemPoppetMixin_Bauble —— 附魔人偶
同样 implements IBaubleExpanded(ItemPoppetMixin_Bauble.java:33),
但可用槽位只有挂饰(charm)一种:
@Unique
private static final String[] witcheryExtras$poppetBaubleTypes = { BaubleExpandedSlots.charmType };
(ItemPoppetMixin_Bauble.java:36)
9 种人偶类型(全部 @Final @Shadow,ItemPoppetMixin_Bauble.java:40-66):
earthPoppet、waterPoppet、firePoppet、foodPoppet、toolPoppet、
deathPoppet、antiVoodooPoppet、vampiricPoppet、poppetProtectionPoppet、
armorPoppet(源码共 10 个 @Shadow 字段,含上列 10 项)。
| 补丁 | 行 | 作用 |
|---|---|---|
@Inject addInformation(TAIL,仅客户端) |
ItemPoppetMixin_Bauble.java:78-84 |
同样用 BaubleItemHelper.addSlotInformation |
@WrapMethod onItemRightClick |
ItemPoppetMixin_Bauble.java:86-89 |
有效人偶 → 装入饰品栏;否则 original.call(...) |
@WrapMethod(static)findBoundPoppetInInventory |
ItemPoppetMixin_Bauble.java:93-99 |
源码注释:// Prioritize player inventory over baubles when checking for poppets ——优先搜玩家背包,再搜饰品栏 |
@SideOnly(Side.CLIENT)标在方法上(ItemPoppetMixin_Bauble.java:77、ItemGeneralMixin_Bauble.java:44),因此 tooltip 补丁只在客户端存在。
门控的双重性
| 层次 | 机制 | 位置 |
|---|---|---|
| Mixin 是否应用 | .addRequiredMod(TargetedMod.BAUBLES_EXPANDED) |
Mixins.java:53 |
| 槽位是否申请 | Loader.isModLoaded("Baubles|Expanded") |
WitcheryExtras.java:63 |
没装 Baubles Expanded 时这 3 个 Mixin 完全不加载, Witchery 的钥匙/人偶就只能放背包,与原版行为一致。
📌
dependencies.gradle里 Baubles-Expanded 是compileOnly—— 编译需要,运行时可选。文件末尾两行// Uncomment to test baubles compat与//devOnlyNonPublishable('com.github.GTNewHorizons:Baubles-Expanded:2.2.22-GTNH:dev')是注释掉的开发期依赖(dependencies.gradle:13-14),不参与构建。
关联
- 3 个 Mixin 在总表中的位置见 Mixin 补丁总表
- Baubles Expanded 自身内容见 baubles-expanded 分类页