Solved Get wheat seeds from drops

Discussion in 'Spigot Plugin Development' started by Dr.Night, Jan 18, 2020.

  1. Hello. I am trying to set up a small plugin for a few modifications to my server.

    I am trying to replant crops while picking them up (right click).

    The problem right now is, that i cant plant new seeds from the seeds from the drop or from inventory. It works fine for potatoes tho.

    My code is (@eventhandler is in the code, just not pasted here):
    Code (Text):
        public void onWheat(PlayerInteractEvent e) {
            if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                Block block = e.getClickedBlock();
                if (block.getType() == Material.WHEAT || block.getType() == Material.LEGACY_WHEAT || block.getType() == Material.LEGACY_CROPS) {
                    if (!e.getPlayer().hasPermission("smalladd.crops")) {
                        return;
                    }
                 
                    if(block.getData() != 7) {
                        return;
                    }
                 
                    e.getPlayer().sendMessage(block.getDrops().toString());
                 
                    if (block.getDrops().contains(new ItemStack(Material.WHEAT_SEEDS))) {
                        e.getPlayer().sendMessage("wtf");
                        block.getDrops().remove(new ItemStack(Material.WHEAT_SEEDS, 1));
                        block.breakNaturally();
                        block.setType(Material.WHEAT);
                    } else if (e.getPlayer().getInventory().contains(new ItemStack(Material.WHEAT_SEEDS))) {
                        e.getPlayer().sendMessage("wtf2");
                        e.getPlayer().getInventory().remove(new ItemStack(Material.WHEAT_SEEDS, 1));
                        block.breakNaturally();
                        block.setType(Material.WHEAT);
                    } else
                        block.breakNaturally();
                    e.setCancelled(true);
                 
                }
            }
        }
     
  2. Block#getDrops returns a Collection of ItemStacks.
    I assume this collection contains the wheat as well as the seeds. This means you will have to search in the drops for the seeds and decrement the ItemStack (if there are any seeds).
    Also, there is a BlockBreakEvent that triggers when a player tries to break a block (which would be the case here).
     
  3. Thank you, I know about the BlockBreakEvent, but i have this nostalgia about right-click farming from the modpacks i played.
    Should I just make a foreach loop and search trough the collection?
     
  4. That's what I would suggest
     
  5. I have tried your method but it still doesnt work. Here is the code i used:
    Code (Text):
        public void onWheat(PlayerInteractEvent e) {
            if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
                Block block = e.getClickedBlock();
                if (block.getType() == Material.WHEAT || block.getType() == Material.LEGACY_WHEAT || block.getType() == Material.LEGACY_CROPS) {
                    if (!e.getPlayer().hasPermission("smalladd.wheat")) {
                        return;
                    }
                   
                    if(block.getData() != 7) {
                        return;
                    }
                   
                    boolean SeedInDrop = false;
                    for (ItemStack is : block.getDrops()) {
                        if (is == new ItemStack(Material.WHEAT_SEEDS))
                            SeedInDrop = true;
                    }
                   
                    boolean SeedInInv = false;
                    for (ItemStack is : e.getPlayer().getInventory()) {
                        if (is == new ItemStack(Material.WHEAT_SEEDS))
                            SeedInInv = true;
                    }
                   
                    if (SeedInDrop) {
                        e.getPlayer().sendMessage("Seed in drop");
                        block.getDrops().remove(new ItemStack(Material.WHEAT_SEEDS, 1));
                        block.breakNaturally();
                        block.setType(Material.WHEAT);
                    } else if (SeedInInv) {
                        e.getPlayer().sendMessage("Seed in inv");
                        e.getPlayer().getInventory().remove(new ItemStack(Material.WHEAT_SEEDS, 1));
                        block.breakNaturally();
                        block.setType(Material.WHEAT);
                    } else
                        block.breakNaturally();
                    e.setCancelled(true);
                   
                }
            }
        }
     
  6. Did you try to print out what the collection actually contains?
    Also...
    Code (Java):
    Object a;
    Object b;

    a == b
    returns true if, and only if the two Objects are identical
    Since you create a new ItemStack, it is more than unlikely that a comparison
    Code (Java):
    is == new ItemStack(Material.WHEAT_SEEDS)
    will never return true (unless we are talking about black wizardry, in that case, that equation could return true)
    For how to actually check if the ItemStack actually contains WheatSeeds, you have several options, for example:
    Code (Java):
    ItemStack is;
    is.getType() == Material.WHEAT_SEEDS
    is.isSimilar(new ItemStack(Material.WHEAT_SEEDS))
     
     
    • Agree Agree x 1
    • Useful Useful x 1
  7. I wrote this to determine what Items a block will drop taking the breaking item into account:


    Code (Java):
    public class BlockBreak_1_14 implements BreakEvaluator{

        @Override
        public List<ItemStack> eval(World world, ItemStack breakItem, BlockState blockToBreak) {
            WorldServer ws = ((CraftWorld) world).getHandle();
            IBlockData data = ((CraftBlockState)blockToBreak).getHandle();
            BlockPosition position = ((CraftBlockState)blockToBreak).getBlock().getPosition();
         
            LootTableInfo.Builder info = new LootTableInfo.Builder(((CraftWorld) world).getHandle())
                    .set(LootContextParameters.POSITION, position)
                    .set(LootContextParameters.BLOCK_STATE, data)
                    .setOptional(LootContextParameters.BLOCK_ENTITY, ws.getTileEntity(position))
                    .setOptional(LootContextParameters.TOOL, CraftItemStack.asNMSCopy(breakItem));
         
            return data.a(info).stream().map(CraftItemStack::asBukkitCopy).collect(Collectors.toList());
        }

    }
     
  8. Wait... so are you now a big fan of streams or not?
     
  9. When i first learned about them and understood them i wrote 1/3 of my code just in streams. It was stupid.
    Its a hate/love relationship at the moment.
    Maybe i can find one of my stupid crazy old streams XD

    PS
    oh god... i used IntStream.rangeClosed(x, y) instead of a for loop for index iteration...
    Screenshot_9.png

    Screenshot_10.png

    Screenshot_7.png

    Just... no
     
    #9 7smile7, Jan 18, 2020
    Last edited: Jan 18, 2020
  10. Thank you! Your explanation helped alot. It works like a charm :D