Jump to content

[1.19.2] Get stack count from Ingredient of a recipe.


N3E0

Recommended Posts

I have a custom recipe that uses JSON to work properly. And everything works right except I cant seem to figure out how to find the stack count for each ingredient of my recipe.

 

Recipe class:

public class AlloyKilnRecipe implements Recipe<SimpleContainer> {
    private final ResourceLocation id;
    private final ItemStack output;
    private final NonNullList<Ingredient> ingredients;

    public AlloyKilnRecipe(ResourceLocation id, ItemStack output, NonNullList<Ingredient> ingredients) {
        this.id = id;
        this.output = output;
        this.ingredients = ingredients;
    }

    @Override
    public boolean matches(SimpleContainer pContainer, Level pLevel) {
        if (pLevel.isClientSide()) return false;
        return (ingredients.get(0).test(pContainer.getItem(0)) && ingredients.get(1).test(pContainer.getItem(1))) ||
               (ingredients.get(0).test(pContainer.getItem(1)) && ingredients.get(1).test(pContainer.getItem(0)));
    }

    public int getIngAmnt(int index) {
        ItemStack[] stacks = ingredients.get(index).getItems();
        for (ItemStack stack : stacks) {
            return stack.getCount();
        }
        return 0;
    }

    @Override
    public NonNullList<Ingredient> getIngredients() {
        return ingredients;
    }

    @Override
    public ItemStack assemble(SimpleContainer pContainer) {
        return output;
    }

    @Override
    public boolean canCraftInDimensions(int pWidth, int pHeight) {
        return true;
    }

    @Override
    public ItemStack getResultItem() {
        return output.copy();
    }

    @Override
    public ResourceLocation getId() {
        return id;
    }

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

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

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

    public static class Serializer implements RecipeSerializer<AlloyKilnRecipe> {
        public static final Serializer INSTANCE = new Serializer();
        public static final ResourceLocation ID = new ResourceLocation(FF.MOD_ID, "alloy_kiln_recipe");

        @Override
        public AlloyKilnRecipe fromJson(ResourceLocation pRecipeId, JsonObject pSerializedRecipe) {
            ItemStack output = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(pSerializedRecipe, "output"));

            JsonArray ingredients = GsonHelper.getAsJsonArray(pSerializedRecipe, "ingredients");
            NonNullList<Ingredient> inputs = NonNullList.withSize(2, Ingredient.EMPTY);
            for (int i = 0; i < ingredients.size(); i++) {
                inputs.set(i, Ingredient.fromJson(ingredients.get(i)));
            }
            return new AlloyKilnRecipe(pRecipeId, output, inputs);
        }

        @Override
        public @Nullable AlloyKilnRecipe fromNetwork(ResourceLocation pRecipeId, FriendlyByteBuf pBuffer) {
            NonNullList<Ingredient> inputs = NonNullList.withSize(pBuffer.readInt(), Ingredient.EMPTY);
            for (int i = 0; i < inputs.size(); i++) {
                inputs.set(i, Ingredient.fromNetwork(pBuffer));
            }
            ItemStack output = pBuffer.readItem();
            return new AlloyKilnRecipe(pRecipeId, output, inputs);
        }

        @Override
        public void toNetwork(FriendlyByteBuf pBuffer, AlloyKilnRecipe pRecipe) {
            pBuffer.writeInt(pRecipe.getIngredients().size());
            for (Ingredient ing : pRecipe.getIngredients()) {
                ing.toNetwork(pBuffer);
            }
            pBuffer.writeItemStack(pRecipe.getResultItem(), false);
        }
    }
}

And here is my recipe.json

{
  "type": "forgedfactory:alloy_kiln_recipe",
  "ingredients": [
    {
      "item": "minecraft:iron_ingot",
      "count": 3
    },
    {
      "item": "minecraft:gold_ingot"
    }
  ],
  "output": {
    "item": "minecraft:diamond",
    "count": 3
  }
}

Could someone tell me what I would have to do?

The getIngAmount method just returns 1 even though I have a count defined for the iron ingots.

Link to comment
Share on other sites

Custom recipes are not something I know much about, but...

 

I think you are using the vanilla ingredient parser for "item" which if you look at Ingredient.valueFromJson() does not parse a "count" field.

It does new ItemStack(item) - i.e. the count is 1

Infamously, vanilla's crafting table is hardwired to always have a count of 1 in its recipe input slots.

 

You can see forge's custom Ingredient serializers being registered in ForgeMod.registerRecipeSerializers()

e.g. https://github.com/MinecraftForge/MinecraftForge/blob/0e66b7b21757e510aef706ca320881b9eb268822/src/generated_test/resources/data/data_gen_test/recipes/exact_nbt_ingredient.json

Or you can always create your own.

Edited by warjort

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

  • 3 months later...
On 11/30/2022 at 9:09 PM, N3E0 said:

So should I replace the json with something else or should I change the class.

It's great when all we get is a link that doesn't tell us how to implement something.

Great question, though. I've got the same problem trying to figure out how to get the ingredient count.

  "ingredients": [
    {
      "item": "foundations:rough_stone_rock",
      "count": 4
    }
  ]

So I wrote a method called from `fromJson(...)`. Iterating the 

        public MasonryBenchRecipe fromJson(ResourceLocation containerId, JsonObject json) {
            JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients");
            NonNullList<Ingredient> inputs = NonNullList.withSize(ingredients.size(), Ingredient.EMPTY);
            
            for (int i = 0; i < ingredients.size(); ++i) {
                Ingredient ingredient = getIngredient(ingredients.get(i).getAsJsonObject());
                inputs.set(i, ingredient);
            }
                                                   
            return new MasonryBenchRecipe(containerId, output, inputs);
        }

        private Ingredient getIngredient(JsonObject json) {
            Ingredient ingredient = Ingredient.fromJson(json);
            int count = 1;

            if (json.getAsJsonObject().has("count")) {
                count = GsonHelper.getAsInt(json, "count");
            }
            
            ItemStack itemStack = ingredient.getItems()[0];
            itemStack.setCount(count);

            return  ingredient;
        }

And when the recipe initializes, now the ItemStack has a size of 4 according to the recipe.

Edited by badkraft
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.