Need help with craftinggrids, remove recipe items

Discussion in 'Plugin Development' started by Williamsson, Apr 11, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Williamsson

    Hi!
    This is what I want:
    When the random number is 1, the crafting shall be cancelled. This is done.
    Now I want to remove one (crafted-)item recipe from all the items in the craftinggrid.
    Using .clear() removes ALL items from the crafting grid, wich is not what I want.

    Anyone have a idea of what I could do?


    Code:
    if (rnd.nextInt(3) == 1) {
                       
            event.setCancelled(true);
           
          //Need something to remove one recipe of the intended crafted item
               
            player.sendMessage("You failed to craft this item.");
    }
     
  2. Offline

    sd5

    Why not making a random from 1-9 and then clear the inventory slot with this number?
     
  3. Offline

    Williamsson

    Because clearing a slot would remove all contents from that slot, right?
    All I want to remove is one of the recipes, so if the users have material for two iron swords but fails to craft one of them, the other material shouldn't be removed.
     
  4. Can't you get the recipe, go through all items, and remove them from the players inventory?
     
  5. Offline

    Williamsson

    That was my initial thought, but i couldnt figure out how to do it.
    I've got the event and a item stack, and i found a getrecipe, but then i got stuck.
    So how would i go about to do that?
    Thanks :)
     
  6. I've never done such things. But I see there are several types of recipes.

    FurnaceRecipe, you can use .getInput to get an itemstack of ingredients.
    ShapedRecipe, you can use .getIngredientList to get a list of ingredients.
    ShapelessRecipe, you can use .getIngredientMap to get a map of ingredients.

    So first check what type of recipe it is. (The current recipe is called recipeOfCurrentCreation. This needs to be changed to what ever you use for the used recipe.)
    Code:
    List<ItemStack> itemList = new ArrayList<ItemStack>();
    if(recipeOfCurrentCreation instanceof FurnaceRecipe) {
        FurnaceRecipe recipe = (FurnaceRecipe) recipeOfCurrentCreation;
        itemList.add(recipe.getInput);
    } else if (recipeOfCurrentCreation instanceof ShapedRecipe) {
        ShapedRecipe recipe = (ShapedRecipe) recipeOfCurrentCreation;
        itemList.addAll(recipe. getIngredientList());
    } else if (recipeOfCurrentCreation instanceof ShapelessRecipe) {
        ShapelessRecipe = (ShapelessRecipe) recipeOfCurrentCreation;
        itemList.addAll(recipe.getIngredientMap().getValues());
    } else {
        // Shouldn't get here!
    }
     
    if(!itemList.isEmpty()) {
        for(ItemStack i:itemList) {
            player.getInventory().removeItem(i);
        }
        player.updateInventory(); // Don't know if this is needed...
    }
    
    PS: All code is not tested!
     
  7. Offline

    Williamsson


    Most of it seems to work, except for one part:

    Code:
    } else if (craftedItemRecipe instanceof ShapedRecipe) {
                               
             ShapedRecipe recipe = (ShapedRecipe) craftedItemRecipe;
            itemList.addAll(recipe.getIngredientMap());
                               
    }
    Eclipse tells me "The method addAll(Collection<? extends ItemStack>) in the type List<ItemStack> is not applicable for the arguments (Map<Character,ItemStack>)" and says "Use .add instead", and when I use .add it tells me "The method add(ItemStack) in the type List<ItemStack> is not applicable for the arguments
    (Map<Character,ItemStack>)".

    Any idea of what to do? :)
     
  8. That's probably because I said something else. Don't forget the getValues() after the getIngredientMap() ;)

    Code:
    itemList.addAll(recipe.getIngredientMap().getValues());
    Furnace returns a single ItemStack - ItemStack
    Shaped returns a list of ItemStacks - List<ItemStack>
    Shapeless returns a map of ItemStacks - Map<Char, ItemStack>

    Just basic java to put these values in a new list right!? ;)
     
  9. Offline

    Williamsson

    Fair enough! :D
    Yeah, it is, I'll blame on me actually beeing a php programmer still learning java.. :)


    Anyhow, that gave me the following error:

    Code:
    org.bukkit.event.EventException
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:303)
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:459)
        at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:1071)
        at net.minecraft.server.Packet102WindowClick.handle(SourceFile:28)
        at net.minecraft.server.NetworkManager.b(NetworkManager.java:229)
        at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:113)
        at net.minecraft.server.NetworkListenThread.a(NetworkListenThread.java:78)
        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:551)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:449)
        at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)
    Caused by: java.lang.NullPointerException
        at org.bukkit.craftbukkit.inventory.CraftInventory.removeItem(CraftInventory.java:309)
        at swe.kbk.Cinnajobs.CraftListener.CraftItem(CraftListener.java:145)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:301)
        ... 10 more
    And line 145 is where we're trying to remove the item;

    Code:
    } else if (craftCancel[craftId]) {
                        if (rnd.nextInt(2) == 1) {
                         
                            event.setCancelled(true);
                         
                            Recipe craftedItemRecipe = event.getRecipe();
                            List<ItemStack> itemList = new ArrayList<ItemStack>();
                         
                            if(craftedItemRecipe instanceof FurnaceRecipe) {
                             
                                FurnaceRecipe recipe = (FurnaceRecipe) craftedItemRecipe;
                                itemList.add(recipe.getInput());
                             
                            } else if (craftedItemRecipe instanceof ShapedRecipe) {
                             
                                ShapedRecipe recipe = (ShapedRecipe) craftedItemRecipe;
                                itemList.addAll(recipe.getIngredientMap().values());
                             
                            } else if (craftedItemRecipe instanceof ShapelessRecipe) {
                             
                                ShapelessRecipe recipe = (ShapelessRecipe) craftedItemRecipe;
                                itemList.addAll(recipe.getIngredientList());
                             
                            } else {
                                // Shouldn't get here!
                            }
                         
                            if(!itemList.isEmpty()) {
                                for(ItemStack i:itemList) {
                                    player.getInventory().removeItem(i);
                                }
                            }                     
                         
                            player.sendMessage("You failed to craft this item.");
     
  10. Ahh... It probably add null values when it has empty slots in the recipe.

    Just replace this:
    Code:
    if(!itemList.isEmpty()) {
        for(ItemStack i:itemList) {
            player.getInventory().removeItem(i);
        }
    }
    with
    Code:
    if(!itemList.isEmpty()) {
        for(ItemStack i:itemList) {
            if(i != null) {
                player.getInventory().removeItem(i);
            }
        }
    }
     
  11. Offline

    Williamsson

    Well that removed the error, but the items in the crafting grid isn't removed :/

    EDIT:
    By using event.getInventory.removeItem(i) it works, it removes the correct ammount of for example iron ingots, although from one spot in the inventory. But that's not extremely important, it just looks a bit ugly :p

    Thanks for your help! I'll now go on a bughunt :)
     
Thread Status:
Not open for further replies.

Share This Page