跳到主要内容

31配方类型

代码

新建一个recipe包:

GemPolishingRecipe:

public class GemPolishingRecipe implements Recipe<SimpleInventory> {
private final ItemStack output;
private final List<Ingredient> recipeItems;

public GemPolishingRecipe(List<Ingredient> ingredients, ItemStack itemStack) {
this.output = itemStack;
this.recipeItems = ingredients;
}

@Override
public boolean matches(SimpleInventory inventory, World world) {
if(world.isClient()) {
return false;
}

return recipeItems.get(0).test(inventory.getStack(0));
}

@Override
public ItemStack craft(SimpleInventory inventory, DynamicRegistryManager registryManager) {
return output;
}

@Override
public boolean fits(int width, int height) {
return true;
}

@Override
public ItemStack getResult(DynamicRegistryManager registryManager) {
return output;
}

@Override
public DefaultedList<Ingredient> getIngredients() {
DefaultedList<Ingredient> list = DefaultedList.ofSize(this.recipeItems.size());
list.addAll(recipeItems);
return list;
}

@Override
public RecipeSerializer<?> getSerializer() {
return Serializer.INSTANCE;
}

@Override
public RecipeType<?> getType() {
return Type.INSTANCE;
}

public static class Type implements RecipeType<GemPolishingRecipe> {
public static final Type INSTANCE = new Type();
public static final String ID = "gem_polishing";
}

public static class Serializer implements RecipeSerializer<GemPolishingRecipe> {
public static final Serializer INSTANCE = new Serializer();
public static final String ID = "gem_polishing";

public static final Codec<GemPolishingRecipe> CODEC = RecordCodecBuilder.create(in -> in.group(
validateAmount(Ingredient.DISALLOW_EMPTY_CODEC, 9).fieldOf("ingredients").forGetter(GemPolishingRecipe::getIngredients),
RecipeCodecs.CRAFTING_RESULT.fieldOf("output").forGetter(r -> r.output)
).apply(in, GemPolishingRecipe::new));

private static Codec<List<Ingredient>> validateAmount(Codec<Ingredient> delegate, int max) {
return Codecs.validate(Codecs.validate(
delegate.listOf(), list -> list.size() > max ? DataResult.error(() -> "Recipe has too many ingredients!") : DataResult.success(list)
), list -> list.isEmpty() ? DataResult.error(() -> "Recipe has no ingredients!") : DataResult.success(list));
}

@Override
public Codec<GemPolishingRecipe> codec() {
return CODEC;
}

@Override
public GemPolishingRecipe read(PacketByteBuf buf) {
DefaultedList<Ingredient> inputs = DefaultedList.ofSize(buf.readInt(), Ingredient.EMPTY);

for(int i = 0; i < inputs.size(); i++) {
inputs.set(i, Ingredient.fromPacket(buf));
}

ItemStack output = buf.readItemStack();
return new GemPolishingRecipe(inputs, output);
}

@Override
public void write(PacketByteBuf buf, GemPolishingRecipe recipe) {
buf.writeInt(recipe.getIngredients().size());

for (Ingredient ingredient : recipe.getIngredients()) {
ingredient.write(buf);
}

buf.writeItemStack(recipe.getResult(null));
}
}
}

ModRecipes:

public class ModRecipes {
public static void registerRecipes() {
Registry.register(Registries.RECIPE_SERIALIZER, new Identifier(TutorialMod.MOD_ID, GemPolishingRecipe.Serializer.ID),
GemPolishingRecipe.Serializer.INSTANCE);
Registry.register(Registries.RECIPE_TYPE, new Identifier(TutorialMod.MOD_ID, GemPolishingRecipe.Type.ID),
GemPolishingRecipe.Type.INSTANCE);
}
}

在主类中注册:

ModRecipes.registerRecipes();

修改原来的宝石抛光台为动态替换合成表:

GemPolishingStationBlockEntity:

private void craftItem() {
Optional<RecipeEntry<GemPolishingRecipe>> recipe = getCurrentRecipe();

this.removeStack(INPUT_SLOT, 1);

this.setStack(OUTPUT_SLOT, new ItemStack(recipe.get().value().getResult(null).getItem(),
getStack(OUTPUT_SLOT).getCount() + recipe.get().value().getResult(null).getCount()));
}

private boolean hasRecipe() {
Optional<RecipeEntry<GemPolishingRecipe>> recipe = getCurrentRecipe();

return recipe.isPresent() && canInsertAmountIntoOutputSlot(recipe.get().value().getResult(null))
&& canInsertItemIntoOutputSlot(recipe.get().value().getResult(null).getItem());
}

private Optional<RecipeEntry<GemPolishingRecipe>> getCurrentRecipe() {
SimpleInventory inv = new SimpleInventory(this.size());
for(int i = 0; i < this.size(); i++) {
inv.setStack(i, this.getStack(i));
}

return getWorld().getRecipeManager().getFirstMatch(GemPolishingRecipe.Type.INSTANCE, inv, getWorld());
}

最后在data目录下加入合成表:

resources/data/tutorialmod/recipes/diamond_from_gem_polishing.json:

{
"type": "tutorialmod:gem_polishing",
"ingredients": [
{
"item": "minecraft:coal"
}
],
"output": {
"item": "minecraft:diamond"
}
}

resources/data/tutorialmod/recipes/ruby_from_gem_polishing.json:

{
"type": "tutorialmod:gem_polishing",
"ingredients": [
{
"item": "tutorialmod:raw_ruby"
}
],
"output": {
"item": "tutorialmod:ruby",
"count": 3
}
}

效果

一个煤炭变为一个砖石

image-20240825164832135

一个红宝石矿变为3个红宝石

image-20240825164839458