[SOLVED] Get the ItemStack that would drop after successful mining

Discussion in 'Plugin Development' started by JoshuaBehrens, Oct 10, 2011.

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

    JoshuaBehrens

    Hey guys,

    I saw a snippet using craftbukkit to get the ItemStack (amount, material/id, data) that would be dropped when mining it. I couldn't fint it so I tried to recreate and try all available things from net.minecraft.server.block but without any success. Anybody got this snippet ?

    Greetz Joshua
     
  2. Offline

    JoshuaBehrens

    Push

    If nobody can help I have to get it hardcoded into the plugin.

    Greetings Joshua
     
  3. Offline

    bergerkiller

    I use this in NoLagg to manually spawn droppings during explosions. It is basically taken over from within Bukkit:
    Code:
    Block b = event.getBlock(); //the block to drop
    //spawn
    int x = b.getLocation().getBlockX();
    int y = b.getLocation().getBlockY();
    int z = b.getLocation().getBlockZ();
    int id = b.getTypeId();
    if (id > 0 && id != Material.FIRE.getId()) {
        net.minecraft.server.Block bb = net.minecraft.server.Block.byId[id];
        if (bb != null) {
            bb.dropNaturally(world, x, y, z, world.getData(x, y, z), yield);
        }
     }
     
    JoshuaBehrens likes this.
  4. Offline

    JoshuaBehrens

    I just tried it, but what value got yield ? If I use 0.0f there is no drop. And when I set it to 1.0f it'll be thousands of stacks. The server and minecraft crashes in both cases.
     
  5. Offline

    bergerkiller

    @JoshuaBohrens you will probably have to modify it, explosion yield could change a lot I guess.

    Here:
    Code:
    Block b = event.getBlock(); //the block to get an itemstack from
    net.minecraft.server.World world = ((CraftWorld) b.getWorld()).getHandle();
    int x = b.getX();
    int y = b.getY();
    int z = b.getZ();
    int dropid = world.getData(x, y, z);
    Material droptype = Material.getMaterial(dropid);
     
  6. Offline

    LartTyler

    Why not just:
    Code:
    ItemStack toDrop = new ItemStack(ev.getBlock().getTypeId());
    Location breakerLoc = ev.getPlayer().getLocation();
    int desiredYield = config.getInt("yields." + ev.getBlock().getType().name());
    
    toDrop.setAmount(desiredYield);
    breakerLoc.getWorld().dropItemNaturally(breakerLoc, toDrop);
    
    Of course, you would replace desiredYield with whatever method you use to determine the desired yield of the destroyed block.

    Hope this helps,


    Tyler
     
  7. Offline

    JoshuaBehrens

    @LartTyler: this would just drop the block as it is !?
    @bergerkiller: Why didn't I get it, that I can use the normal dropping method ? :D thanks for that hint

    But the amount differ from block to block. This must be hardcoded or is there a in-build possibility ?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 20, 2016
  8. Offline

    bergerkiller

    Problem is that the dropped item type is not the same as the block type, so using block.getTypeId() will cause you to mine a stone item instead of cobblestone when a stone block is destroyed. I'm confused to how to do this too now, could be it is hardcoded in onBlockBreak.
     
  9. Offline

    JoshuaBehrens

    ? Does this mean world.getData just gives the real TypeId and not the dropped ?
     
  10. Offline

    bergerkiller

    @JoshuaBehrens afraid it is yes.

    After looking at the coding, this works:
    Code:
    Block b = event.getBlock(); //to drop
    net.minecraft.server.Block nb = net.minecraft.server.Block.byId[b.getTypeId()];
    if (nb != null) {
         int dropid = b.a(0, null);
         Material type = Material.getMaterial(dropid);
         //spawn stack using type here
    }
    
    The a(int, random) function returns the item id to drop when broken.

    It could be you need to supply the random object from the world the block is in, but no idea what the integer argument is for.
     
  11. Offline

    JoshuaBehrens

    Where do you look up the coding ?
    I always wonder what the a-functions are for. I'll play around with the values and report my solution.
     
  12. Offline

    bergerkiller

    @JoshuaBehrens I have the bukkit, craftbukkit and net.minecraft.server source code in a folder locally. (obfuscated that is). I hate the Github source viewer...it's laggy, line nrs don't match and it doesn't allow long lines.

    You can view and download the net.minecraft.server source from MC-dev on github. You can copy n replace craftbukkit over it to show the entire craftbukkit source.
     
  13. Offline

    nisovin

    Passing 1.0 as the yield should have worked fine, it shouldn't create extra items. Unless I'm missing something in the code of that method. Also, the integer field for Block.a() is the data value.
     
  14. Offline

    JoshuaBehrens

    Shall I make a video of it ? I almost got the best method.
     
  15. Offline

    nisovin

    I just tested this:
    Code:
    public void onBlockBreak(BlockBreakEvent event) {
            Block b = event.getBlock();
    
    net.minecraft.server.Block.byId[event.getBlock().getTypeId()].dropNaturally(((CraftWorld)b.getWorld()).getHandle(), b.getX(), b.getY(), b.getZ(), b.getData(), 1.0F);
        }
    It seems to work fine.
     
    JoshuaBehrens likes this.
  16. Offline

    JoshuaBehrens

    That's workin perfectly. The thousands of dropped blocks are a fail of mine...
     
Thread Status:
Not open for further replies.

Share This Page