Solved Empty/Null Recipes?

Discussion in 'Spigot Plugin Development' started by Qruet, Jan 13, 2020.

Thread Status:
Not open for further replies.
  1. I have a very bizarre case where for some reason, air recipes are being registered to the client. One of the features of my plugin is adding a new crafting recipe for every physical block type. For some reason, AIR is considered one of those types, even though I've gone out my way to ensure such material types are not translated into a recipe. No errors are thrown so there's not much I can provide except for some code snippets and a couple of images.

    Code Snippet:
    Code (Java):
        private static final LinkedList<ShapedRecipe> REGISTERED_RECIPES = new LinkedList<>();
        private static final LinkedList<Material> BLACKLISTED_TYPES = new LinkedList<>();
        private static final Collection<Material> RECIPE_TYPES;

        static {
            BLACKLISTED_TYPES.addAll(Arrays.asList(
                    Material.AIR, Material.CAVE_AIR, Material.VOID_AIR,
                    Material.BEDROCK, Material.BARRIER));

            RECIPE_TYPES = Arrays.stream(Material.values()).filter(value -> {
                try {
                    Field field = Material.class.getField(value.name());
                    return !field.isAnnotationPresent(Deprecated.class)
                            && !BLACKLISTED_TYPES.contains(value)
                            && value.isSolid()
                            && value.isBlock();
                } catch (NoSuchFieldException | SecurityException e) {
                    return false;
                }
            }).collect(Collectors.toList());
        }

     
    Snippet responsible for reading the material types and registering the recipes:
    Code (Java):
                    for (Material mat : RECIPE_TYPES) {
                        NamespacedKey key = new NamespacedKey(JavaPlugin.getPlugin(MainReinforce.class), "REINFORCED_" + mat.name().toUpperCase());

                        ItemStack item = new ItemStack(mat, 1);

                        ItemMeta meta = item.getItemMeta();
                        meta.setDisplayName(T.C("&fReinforced " + WordUtils.capitalize(mat.toString().toLowerCase().replaceAll("_", " "))));
                        meta.addEnchant(Enchantment.DURABILITY, 1, true);
                        meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
                        meta.setLore(new ArrayList<String>() {{
                            add(T.C("&7Unbreaking"));
                        }});
                        item.setItemMeta(meta);

                        ShapedRecipe recipe = new ShapedRecipe(key, item);
                        recipe.shape(" S ", "SSS", " S ");
                        recipe.setIngredient('S', mat);
                        recipe.setGroup("reinforced");

                        Bukkit.broadcastMessage("Mat -> " + mat + " Result -> " + recipe.getResult().getType()); //never prints AIR or anything related to material type AIR

                        Tasky.sync(t1 -> {
                            Bukkit.addRecipe(recipe);
                        });
                        REGISTERED_RECIPES.add(recipe);
                    }
    Snippet related to registering the recipes to the player:
    Code (Java):
            for (ShapedRecipe recipe : REGISTERED_RECIPES) {
                player.discoverRecipe(recipe.getKey());
            }
    Images proving my sanity:
    [​IMG]

    [​IMG]
     
    #1 Qruet, Jan 13, 2020
    Last edited: Jan 13, 2020
  2. md_5

    Administrator Developer

    Did you define api-version in plugin.yml?
     
  3. Yes sir. Set to 1.15
     
  4. So if I am reading this correctly, you are looping all Materials (that are blocks) and creating recipes for them?!?!

    The issue could be you are registering recipes for blocks which have a different material for their item.
    Ex: Material.POTATO (item) and Material.POTATOES (block), so if you try create a recipe for POTATOES its just going to be air in the recipe book.
     
  5. Hmm very possible, Ill look into that.
     
  6. I applied the suggestion and it has helped removed some of the air recipes, however 22 air recipes still remain.
    Here is a list of registered recipe results. I've gone through it several times and I haven't noticed anything that could potentially break the recipes, perhaps someone might be able to spot something?

    Here is my updated filter:
    Code (Java):
            BLACKLISTED_TYPES.addAll(Arrays.asList(
                    Material.AIR, Material.CAVE_AIR, Material.VOID_AIR,
                    Material.POTATOES, Material.CARROTS, Material.WHEAT, Material.COCOA, Material.BEETROOTS,
                    Material.NETHER_WART, Material.PISTON_HEAD,
                    Material.TURTLE_EGG, Material.SPAWNER,
                    Material.PETRIFIED_OAK_SLAB,
                    Material.CHIPPED_ANVIL, Material.DAMAGED_ANVIL, Material.FARMLAND, Material.FROSTED_ICE,

                    Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK,
                    Material.INFESTED_CHISELED_STONE_BRICKS, Material.INFESTED_COBBLESTONE,
                    Material.INFESTED_CRACKED_STONE_BRICKS, Material.INFESTED_MOSSY_STONE_BRICKS,
                    Material.INFESTED_STONE, Material.INFESTED_STONE_BRICKS,
                    Material.END_PORTAL, Material.NETHER_PORTAL,
                    Material.BEDROCK, Material.BARRIER));

            RECIPE_TYPES = Arrays.stream(Material.values()).filter(value -> {
                try {
                    Field field = Material.class.getField(value.name());
                    return !field.isAnnotationPresent(Deprecated.class)
                            && !BLACKLISTED_TYPES.contains(value)
                            && value.isSolid()
                            && value.getHardness() > 0
                            && value.isBlock();
                } catch (NoSuchFieldException | SecurityException e) {
                    return false;
                }
            }).collect(Collectors.toList());
    Debugged Output:
    https://pastebin.com/rt0WSDWb
     
  7. You could try this method isItem to make sure the result of the recipe is an item a player can obtain
     
    • Winner Winner x 1
  8. Haha, works like a charm. Wouldn't have thought to use it since I assumed it's basically the opposite of isBlock. Thread closed & solved.
     
    • Friendly Friendly x 1
Thread Status:
Not open for further replies.