Skip to content

自定义合成表 ​

玩家在工作台/背包合成区按指定摆放消耗材料得到新物品——摆放方式 + 产物就是合成表。这一篇讲怎么用代码注册自定义合成表。

合成表的文字表述 ​

用字母代表材料,按行列出摆放。比如"8 金锭 + 1 铁锭 合成 1 绿宝石":

xxx
xyx
xxx

x 是金锭、y 是铁锭。中间放铁锭、周围一圈金锭。

空位用空格 ​

中间不放东西(像熔炉那样 8 个围一圈):

xxx
x x
xxx

中间那个位置在代码里用空格表示,不是 AIR。

非正方形也行 ​

合成表不一定是 3×3,可以是任意 m×n:

xx    # 2×2(合成台)
xx

注册合成表 ​

以"金锭围铁锭合成绿宝石"为例,在 onEnable 里:

java
@Override
public void onEnable() {
    ShapedRecipe recipe = new ShapedRecipe(
        new ItemStack(Material.EMERALD) // 合成产物
    )
    .shape("xxx", "xyx", "xxx")          // 摆放方式
    .setIngredient('x', Material.GOLD_INGOT) // x = 金锭
    .setIngredient('y', Material.IRON_INGOT); // y = 铁锭

    getServer().addRecipe(recipe);
}

产物数量

改产物 ItemStack 的 amount 能一次合成多个:new ItemStack(Material.EMERALD, 3)。

空位示例 ​

8 金锭围一圈合成绿宝石(中间空):

java
ShapedRecipe recipe = new ShapedRecipe(new ItemStack(Material.EMERALD))
    .shape("xxx", "x x", "xxx") // 中间是空格
    .setIngredient('x', Material.GOLD_INGOT);

getServer().addRecipe(recipe);

各种摆放尺寸 ​

shape 参数个数不限,能表示任意尺寸:

java
.shape("x")              // 1×1(像按钮)
.shape("xx", "xx")       // 2×2(像工作台)
.shape("xx", "xx", "xx") // 2×3(像门)

摆放位置是否固定 ​

java
.shape("xx ","xx ","   ")

这要求玩家只能这样摆:

xx空
xx空
空空空

而不能用等效的镜像摆放:

空空空
xx空
xx空

想让摆放更灵活?

固定的 shape 要求精确位置。若要支持任意位置(无序合成),用 ShapelessRecipe:

java
ShapelessRecipe recipe = new ShapelessRecipe(new ItemStack(Material.EMERALD))
    .addIngredient(8, Material.GOLD_INGOT);
getServer().addRecipe(recipe);

只要材料齐、数量对,任意摆放都能合成。

清理合成表 ​

在 onDisable 里清理你注册的(避免重载时重复):

java
@Override
public void onDisable() {
    getServer().clearRecipes(); // 清空所有合成表(含原版!)
}

clearRecipes 会清空原版

clearRecipes() 清的是全部合成表,包括原版的。慎用——会导致原版工作台配方全没了。若只想移除自己的,建议记录注册的 NamespacedKey 后用 removeRecipe(高版本 API)。

带命名空间的合成表(1.12+) ​

高版本注册合成表建议带 NamespacedKey,便于管理和移除:

java
NamespacedKey key = new NamespacedKey(this, "emerald_recipe");
ShapedRecipe recipe = new ShapedRecipe(key, new ItemStack(Material.EMERALD))
    .shape("xxx", "xyx", "xxx")
    .setIngredient('x', Material.GOLD_INGOT)
    .setIngredient('y', Material.IRON_INGOT);

getServer().addRecipe(recipe);

下一篇粒子与音效。