Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.5] Invalid or unsupported recipe type


Recommended Posts

Trying to add custom crafting type. I'm most likely not registering it right. I get this exeption "Invalid or unsupported recipe type" twice when loading world.

Recipe JOSN:

Spoiler

{
  "type": "futurearmour:fabricating",
  "group": "futurearmour",
  "pattern": [
     "xx",
     " x ",
    "x  x",
     "x x"
  ],
  "key": {
    "x": {
      "item": "minecraft:coal"
    }
  },
  "result": {
    "item": "futurearmour:carbon_fiber"
  }
}

 

Recipe and Serializer:

Spoiler

package com.spu.futurearmour.content.recipes.fabricator;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.spu.futurearmour.content.tileentities.FabricatorControllerTileEntity;
import com.spu.futurearmour.setup.RecipeTypesRegistry;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.*;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.registries.ForgeRegistryEntry;

import javax.annotation.Nullable;
import java.util.Map;
import java.util.Set;

import static com.spu.futurearmour.setup.RecipeTypesRegistry.Types.FABRICATING;

public class FabricatorRecipe implements IRecipe<FabricatorControllerTileEntity> {
    private final IRecipeType<?> type;
    private final ItemStack result;
    private final NonNullList<Ingredient> ingredients;
    private final ResourceLocation id;
    private final String group;


    public FabricatorRecipe(ItemStack result, NonNullList<Ingredient> ingredients, ResourceLocation id, String group) {
        this.ingredients = ingredients;
        this.id = id;
        this.group = group;
        this.type = FABRICATING;
        this.result = result;
    }

    @Override
    public boolean matches(FabricatorControllerTileEntity controllerEntity, World world) {
        return false;
    }

    @Override
    public ItemStack assemble(FabricatorControllerTileEntity controllerEntity) {
        return null;
    }

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

    @Override
    public ItemStack getResultItem() {
        return result;
    }

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

    @Override
    public IRecipeType<?> getType() {
        return type;
    }

    public static int getRowWidth(int row) {
        switch (row) {
            case 0:
                return 2;
            case 1:
                return 3;
            case 2:
                return 4;
            case 3:
                return 3;
            default:
                return 0;
        }
    }

    //region Serializer
    @Override
    public IRecipeSerializer<?> getSerializer() {
        return RecipeTypesRegistry.Serializers.FABRICATING.get();
    }

    private static Map<String, Ingredient> keysFromJson(JsonObject jsonObject) {
        Map<String, Ingredient> map = Maps.newHashMap();
        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            if (entry.getKey().length() != 1) {
                throw new JsonSyntaxException("Invalid key entry: '" + (String) entry.getKey() + "' is an invalid symbol (must be 1 character only).");
            }
            if (" ".equals(entry.getKey())) {
                throw new JsonSyntaxException("Invalid key entry: ' ' is a reserved symbol.");
            }
            map.put(entry.getKey(), Ingredient.fromJson(entry.getValue()));
        }
        map.put(" ", Ingredient.EMPTY);
        return map;
    }

    private static String[] patternFromJson(JsonArray jsonArray) {
        String[] pattern = new String[jsonArray.size()];
        if (pattern.length != 4) {
            throw new JsonSyntaxException("Invalid pattern: " + pattern.length + " rows instead of 4");
        } else {
            for (int i = 0; i < pattern.length; ++i) {
                String patternRow = JSONUtils.convertToString(jsonArray.get(i), "pattern[" + i + "]");
                if (patternRow.length() > getRowWidth(i)) {
                    throw new JsonSyntaxException("Invalid pattern: too many columns, " + getRowWidth(i) + " is maximum");
                }
                if (getRowWidth(i) != patternRow.length()) {
                    throw new JsonSyntaxException("Invalid pattern: row " + i + " has width " + patternRow.length() + "instead of " + getRowWidth(i));
                }
                pattern[i] = patternRow;
            }
            return pattern;
        }
    }

    private static NonNullList<Ingredient> dissolvePattern(String[] pattern, Map<String, Ingredient> ingredientMap) {
        NonNullList<Ingredient> result = NonNullList.withSize(12, Ingredient.EMPTY);
        Set<String> keys = Sets.newHashSet(ingredientMap.keySet());
        keys.remove(" ");

        for (int row = 0; row < pattern.length; row++) {
            for (int ch = 0; ch < pattern[row].length(); ch++) {
                String key = pattern[row].substring(ch, ch + 1);
                Ingredient ingredient = ingredientMap.get(key);
                if (ingredient == null) {
                    throw new JsonSyntaxException("Pattern references symbol '" + key + "' but it's not defined in the key");
                }

                keys.remove(key);
                result.set(ch + getRowWidth(row) * row, ingredient);
            }
        }

        if (!keys.isEmpty()) {
            throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + keys);
        } else {
            return result;
        }
    }

    public static class Serializer extends ForgeRegistryEntry<IRecipeSerializer<?>> implements IRecipeSerializer<FabricatorRecipe> {

        @Override
        public FabricatorRecipe fromJson(ResourceLocation id, JsonObject jsonObject) {
            String group = JSONUtils.getAsString(jsonObject, "group", "");
            Map<String, Ingredient> ingredientMap = keysFromJson(JSONUtils.getAsJsonObject(jsonObject, "key"));
            String[] pattern = patternFromJson(JSONUtils.getAsJsonArray(jsonObject, "pattern"));
            NonNullList<Ingredient> ingredients = dissolvePattern(pattern, ingredientMap);
            ItemStack result = ShapedRecipe.itemFromJson(JSONUtils.getAsJsonObject(jsonObject, "result"));
            return new FabricatorRecipe(result, ingredients, id, group);
        }

        @Nullable
        @Override
        public FabricatorRecipe fromNetwork(ResourceLocation id, PacketBuffer packetBuffer) {
            String group = packetBuffer.readUtf(32767);
            NonNullList<Ingredient> ingredients = NonNullList.withSize(12, Ingredient.EMPTY);

            for(int k = 0; k < ingredients.size(); ++k) {
                ingredients.set(k, Ingredient.fromNetwork(packetBuffer));
            }

            ItemStack result = packetBuffer.readItem();
            return new FabricatorRecipe(result, ingredients, id, group);
        }

        @Override
        public void toNetwork(PacketBuffer packetBuffer, FabricatorRecipe recipe) {
            packetBuffer.writeUtf(recipe.group);

            for(Ingredient ingredient : recipe.ingredients) {
                ingredient.toNetwork(packetBuffer);
            }

            packetBuffer.writeItem(recipe.result);
        }
    }
    //endregion
}

 

Mod main class:

Spoiler

package com.spu.futurearmour;

import com.spu.futurearmour.setup.*;
import com.spu.futurearmour.content.world.OreGeneration;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Mod(FutureArmour.MOD_ID)
public class FutureArmour
{
    public static final String MOD_ID = "futurearmour";

    private static final Logger LOGGER = LogManager.getLogger();

    public static final CreativeItemTab ITEM_GROUP = new CreativeItemTab();

    public FutureArmour() {
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);

        Registration.register();

        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, OreGeneration::generateOres);

        MinecraftForge.EVENT_BUS.register(this);

        final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        final ClientSideOnlyModEventRegistry clientSideOnlyModEventRegistry = new ClientSideOnlyModEventRegistry(modEventBus);
        final ServerSideOnlyModEventRegistry serverSideOnlyModEventRegistry = new ServerSideOnlyModEventRegistry(modEventBus);

        registerCommonEvents(modEventBus);
        DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> clientSideOnlyModEventRegistry::registerClientOnlyEvents);
        DistExecutor.safeRunWhenOn(Dist.DEDICATED_SERVER, () -> serverSideOnlyModEventRegistry::registerServerOnlyEvents);
    }

    private void registerCommonEvents(IEventBus eventBus){

    }

    private void setup(final FMLCommonSetupEvent event){

    }

    @OnlyIn(Dist.CLIENT)
    private void doClientStuff(final FMLClientSetupEvent event) {
        Registration.registerClientOnly(event);
        RenderTypeLookup.setRenderLayer(BlockRegistry.FABRICATOR_CONTROLLER_BLOCK.get(), RenderType.translucent());
    }
}

 

Registration:

Spoiler

package com.spu.futurearmour.setup;

import com.spu.futurearmour.content.ModItemModelsProperties;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;

public class Registration {
    public static void register(){
        ModBlockStateProperties.register();
        BlockRegistry.register();
        ContainerTypeRegistry.register();
        TileEntityTypeRegistry.register();
        ItemRegistry.register();
        RecipeTypesRegistry.register();
    }

    public static void registerClientOnly(FMLClientSetupEvent event){
        ModItemModelsProperties.register();
        ContainerTypeRegistry.registerScreens(event);
    }
}

 

Spoiler

package com.spu.futurearmour.setup;

import com.spu.futurearmour.FutureArmour;
import com.spu.futurearmour.content.recipes.fabricator.FabricatorRecipe;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.function.Supplier;

public final class RecipeTypesRegistry {
    public static void register() {
        Types.register();
        Serializers.register();
    }

    public static final DeferredRegister<IRecipeSerializer<?>> RECIPE_SERIALIZER_TYPES =
            DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, FutureArmour.MOD_ID);

    public static final class Types {
        public static final IRecipeType<FabricatorRecipe> FABRICATING =
                IRecipeType.register(FutureArmour.MOD_ID + ":fabricating");
        public static void register() {
        }
    }

    public static final class Serializers {
        public static final RegistryObject<IRecipeSerializer<FabricatorRecipe>> FABRICATING =
                register("fabricating", FabricatorRecipe.Serializer::new);

        private static <T extends IRecipe<?>> RegistryObject<IRecipeSerializer<T>> register(String name, Supplier<IRecipeSerializer<T>> serializer) {
            return RECIPE_SERIALIZER_TYPES.register(name, serializer);
        }

        public static void register() {
        }
    }

    private static Logger LOGGER = LogManager.getLogger();
}

 

I'd be grateful for any suggestions you might have. Thanks in advance

Link to comment
Share on other sites

4 minutes ago, diesieben07 said:

Do not put the RegistryObject in a separate class from their DeferredRegister. Mainly do not use all those nested classes.

changed the registration part to this, still get the same exception

package com.spu.futurearmour.setup;

import com.spu.futurearmour.FutureArmour;
import com.spu.futurearmour.content.recipes.fabricator.FabricatorRecipe;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraftforge.fml.RegistryObject;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.function.Supplier;

public final class RecipeTypesRegistry {
    public static void register() {
    }

    public static final DeferredRegister<IRecipeSerializer<?>> RECIPE_SERIALIZER_TYPES =
            DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, FutureArmour.MOD_ID);

        public static final IRecipeType<FabricatorRecipe> FABRICATING =
                IRecipeType.register(FutureArmour.MOD_ID + ":fabricating");

        public static final RegistryObject<IRecipeSerializer<FabricatorRecipe>> FABRICATING_SERIALIZER =
                register("fabricating", FabricatorRecipe.Serializer::new);

        private static <T extends IRecipe<?>> RegistryObject<IRecipeSerializer<T>> register(String name, Supplier<IRecipeSerializer<T>> serializer) {
            return RECIPE_SERIALIZER_TYPES.register(name, serializer);
        }

    private static Logger LOGGER = LogManager.getLogger();
}

 

Link to comment
Share on other sites

9 minutes ago, diesieben07 said:

Where do you register your DeferredRegisters? Why do you have all these empty registrer methods?

I use empty register methods to classload all my registry classes

The DefferedRegisters are registered in the constructor of mod's main class
Registration.register();

@Mod(FutureArmour.MOD_ID)
public class FutureArmour
{
    public static final String MOD_ID = "futurearmour";

    private static final Logger LOGGER = LogManager.getLogger();

    public static final CreativeItemTab ITEM_GROUP = new CreativeItemTab();

    public FutureArmour() {
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);

        Registration.register();

        MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, OreGeneration::generateOres);

        MinecraftForge.EVENT_BUS.register(this);
    }

 

Edited by SomeDudeOnTheInternet
Link to comment
Share on other sites

3 minutes ago, diesieben07 said:

Registryation.register calls a bunch of other register methods. You have shown one of them and it is empty and as such accomplishes nothing. Why do you have these empty methods?

From what I understand, referencing the classes in this way should class load them. If it is not a valid way to do it, please tell me.

Edited by SomeDudeOnTheInternet
Link to comment
Share on other sites

Just now, SomeDudeOnTheInternet said:

From what I understand, referencing the classes in this way should class load them. If it is not a valid way to do it, please tell me.

Yes it loads the class, which accomplishes nothing because all the static initializer does is create the DeferredRegister and register its RegistryObjects. Please refer to the documentation.

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
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.

 Share



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hazmat Suit from Mekanism is the problem. I just found it populating itself to the max over and over raising havok in my Refined storage. Not sure why but i deleted it through transmutation and then unistalled it again. This was in Vault hunters
    • [19mai2022 11:08:54.412] [main/INFO] [cpw.mods.modlauncher.Launcher/MODLAUNCHER]: ModLauncher running: args [--username, Bee_Lytho, --version, 1.16.5-forge-36.2.34, --gameDir, C:\Users\vivie\AppData\Roaming\.minecraft, --assetsDir, C:\Users\vivie\AppData\Roaming\.minecraft\assets, --assetIndex, 1.16, --uuid, 9ca0e0921a5c4760809353131bad1432, --accessToken, ????????, --userType, msa, --versionType, release, --launchTarget, fmlclient, --fml.forgeVersion, 36.2.34, --fml.mcVersion, 1.16.5, --fml.forgeGroup, net.minecraftforge, --fml.mcpVersion, 20210115.111550] [19mai2022 11:08:54.421] [main/INFO] [cpw.mods.modlauncher.Launcher/MODLAUNCHER]: ModLauncher 8.1.3+8.1.3+main-8.1.x.c94d18ec starting: java version 1.8.0_51 by Oracle Corporation [19mai2022 11:08:54.475] [main/WARN] [cpw.mods.modlauncher.SecureJarHandler/]: LEGACY JDK DETECTED, SECURED JAR HANDLING DISABLED [19mai2022 11:08:54.814] [main/INFO] [optifine.OptiFineTransformationService/]: OptiFineTransformationService.onLoad [19mai2022 11:08:54.817] [main/INFO] [optifine.OptiFineTransformationService/]: OptiFine ZIP file URL: file:/C:/Users/vivie/AppData/Roaming/.minecraft/mods/OptiFine_1.18.1_HD_U_H4.jar [19mai2022 11:08:54.819] [main/INFO] [optifine.OptiFineTransformationService/]: OptiFine ZIP file: C:\Users\vivie\AppData\Roaming\.minecraft\mods\OptiFine_1.18.1_HD_U_H4.jar [19mai2022 11:08:54.824] [main/INFO] [optifine.OptiFineTransformer/]: Target.PRE_CLASS is available [19mai2022 11:08:55.172] [main/INFO] [net.minecraftforge.fml.loading.FixSSL/CORE]: Added Lets Encrypt root certificates as additional trust [19mai2022 11:08:55.296] [main/INFO] [mixin/]: SpongePowered MIXIN Subsystem Version=0.8.4 Source=file:/C:/Users/vivie/AppData/Roaming/.minecraft/libraries/org/spongepowered/mixin/0.8.4/mixin-0.8.4.jar Service=ModLauncher Env=CLIENT [19mai2022 11:08:55.321] [main/INFO] [optifine.OptiFineTransformationService/]: OptiFineTransformationService.initialize [19mai2022 11:08:56.863] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]: java.lang.AbstractMethodError: Method optifine/OptiFineTransformationService.beginScanning(Lcpw/mods/modlauncher/api/IEnvironment;)V is abstract [19mai2022 11:08:56.863] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at optifine.OptiFineTransformationService.beginScanning(OptiFineTransformationService.java) [19mai2022 11:08:56.863] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.api.ITransformationService.runScan(ITransformationService.java:74) [19mai2022 11:08:56.867] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.TransformationServiceDecorator.runScan(TransformationServiceDecorator.java:114) [19mai2022 11:08:56.870] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.TransformationServicesHandler.lambda$runScanningTransformationServices$8(TransformationServicesHandler.java:115) [19mai2022 11:08:56.870] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.TransformationServicesHandler$$Lambda$204/901205084.apply(Unknown Source) [19mai2022 11:08:56.871] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267) [19mai2022 11:08:56.872] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1612) [19mai2022 11:08:56.873] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) [19mai2022 11:08:56.874] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) [19mai2022 11:08:56.874] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) [19mai2022 11:08:56.875] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) [19mai2022 11:08:56.876] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) [19mai2022 11:08:56.877] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.TransformationServicesHandler.runScanningTransformationServices(TransformationServicesHandler.java:116) [19mai2022 11:08:56.877] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.TransformationServicesHandler.initializeTransformationServices(TransformationServicesHandler.java:63) [19mai2022 11:08:56.878] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.Launcher.run(Launcher.java:76) [19mai2022 11:08:56.879] [main/INFO] [STDERR/]: [java.lang.ThreadGroup:uncaughtException:1052]:     at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)     Thank you  
    • So something like this is what you meant right? I tested it and this setup works I just wanna make sure I did it correctly New Tile: https://pastebin.com/XHduUJcA InputStackHandler: https://pastebin.com/JKZiSska
    • This is how I fixed it not sure this is the correct way, but it works boolean flag = fluidstate.getType() != Fluids.EMPTY; boolean flag = fluidstate.getType() != Fluids.EMPTY; Added this method @Override public boolean canPlaceLiquid(BlockGetter p_54325_, BlockPos p_54326_, BlockState p_54327_, Fluid p_54328_) { return false; }  
    • Hello, I also want to increase the reach attack of some tools. I would like you to help me especially with the PacketHandler and put it in the tools
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.