Apply Bonemeal Effect Programmatically?

Discussion in 'Plugin Development' started by ryanhamshire, Mar 4, 2012.

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

    ryanhamshire

    On my server, I have an issue where there's not enough grass around - too many new players, so we run out of grass and starting a wheat field becomes difficult.

    I want to programmatically apply the bonemeal effect to a grass block to grow tall grass and flowers, but I'm searching the forums and JavaDocs and nothing jumps out at me. How can I do this?
     
  2. Offline

    s1mpl3x

    Dunno if this is exactly what you are looking for, but this should do the trick, although i didn't test it
    Code:
        private void regrow(Block center, int radius){
            Random rnd = new Random();
            int radius_squared = radius * radius;
            Block toHandle;
            for (int x = -radius; x <= radius; x++) {
                for (int z = -radius; z <= radius; z++) {
                    toHandle =  center.getWorld().getHighestBlockAt(center.getX() + x, center.getZ() + z);
                    if (toHandle.getRelative(BlockFace.DOWN).getType() == Material.GRASS) { // Block beneath is grass
                        if (center.getLocation().distanceSquared(toHandle.getLocation()) <= radius_squared) { // Block is in radius
                            if (rnd.nextInt(100) < 66) {    // Random chance
                                toHandle.setType(Material.LONG_GRASS);
                                toHandle.setData((byte) 1);
                            }
                        }
                    }
                }
            }
        }
     
  3. Offline

    ryanhamshire

    Thanks, I can see how this would work for now, but I'd rather apply the bonemeal effect and just let MC do the rest, in case bonemeal's impact changes in the future.

    Can I maybe fake a bonemeal event somehow?
     
  4. Offline

    mushroomhostage

    Yes, you can call into the bone meal "use item" method directly. This is what I use in EnchantMore for the Hoe + Respiration = grow effect:

    Code:
        // Attempt to grow organic structure
        private void growStructure(Location loc, Player player) {
            int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
            World world = loc.getWorld();
    
            // Use bonemeal (white dye/ink) to grow
            CraftItemStack bonemealStack = (new CraftItemStack(Material.INK_SACK, 1, (short)15));
    
            // 'a' unobfuscated = onItemUse
            net.minecraft.server.Item.INK_SACK.a(bonemealStack.getHandle(), ((CraftPlayer)player).getHandle(), ((CraftWorld)world).getHandle(), x, y, z, 0/*unused*/);
        }
    
    It works on at least CraftBukkit 1.1-R4, but will have to be updated for 1.2 to use the new obfuscated onItemUse method name (anyone know what it is? I haven't updated this plugin for 1.2R0.1 yet). Or maybe there is a better, less fragile way to do this, anyone know?
     
  5. Offline

    mushroomhostage

    Anyone trying to update their plugin for 1.1-R8+, the obfuscated "a" method is now named "interactWith":
    Code:
            net.minecraft.server.Item.INK_SACK.interactWith(bonemealStack.getHandle(), ((CraftPlayer)player).getHandle(), ((CraftWorld)world).getHandle(), x, y, z, 0/*unused*/);
    
     
Thread Status:
Not open for further replies.

Share This Page