Block.setType() not working?

Discussion in 'Plugin Development' started by Fauglir, Feb 9, 2012.

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

    Fauglir

    I had this first version of a function in my plugin:

    Code:
    @EventHandler(priority = EventPriority.NORMAL)
        public void onPlaceCobblestone(final BlockPlaceEvent event) {
            Block block = event.getBlock();
            Player player = event.getPlayer();
            Material mat = block.getType();
            if (plugin.pluginEnabled.containsKey(player))
                if (mat.compareTo(Material.COBBLESTONE) == 0 && plugin.pluginEnabled.get(player))
                    block.setType(Material.STONE);
        }
    And worked fine (turned cobblestone to stone automatically). But now I'm trying to do the same thing with new version of Bukkit and it doesn't seem to work. I have this:

    Code:
        @EventHandler(priority = EventPriority.NORMAL)
        public void onPlaceCobblestone(final BlockPlaceEvent event) {
            Block block = event.getBlock();
            Player player = event.getPlayer();
            Material mat = block.getType();
            System.out.println(mat.name());
            if (mat.compareTo(Material.COBBLESTONE) == 0 && plugin.getPlayerEnabled(player))
                //if (plugin.getTypePlugin(player) == 0)    //Free AutoStone
                    block.setType(Material.STONE);
                //More code
        }
    And System.out.println prints in screen 2 values when I'm placing a block. If it's some block except cobblestone it prints BLOCK, BLOCK but when I place cobblestone, it prints COBBLESTONE, STONE but in screen no changes appear.

    Any suggestions?

    Thanks in advance.
     
  2. I'm going to throw something out there and say after block.setType throw a block.getState().update(true)? It should work, don't know why it wouldn't. Might be something with mat.compareTo and/or plugin.getPlayerEnabled
     
  3. Offline

    Fauglir

    I tried with:

    Code:
            if (mat.compareTo(Material.COBBLESTONE) == 0 && plugin.getPlayerEnabled(player)) {
                //if (plugin.getTypePlugin(player) == 0)    //Free AutoStone
                    block.setType(Material.STONE);
                    block.getState().update(true);
                    System.out.println(block.getType().name());
            }
    And the output is STONE :confused: Don't know why in my screen doesn't appear stone when in previous version changing blocks worked fine D:

    The plugin enters in if and checks condition, both are true (because System.out.println(mat.name()) outputs first COBBLESTONE (block being placed) and plugin is enabled), then changes block type, prints STONE and then prints STONE again, I suppose it's because something related to the first println and another kind of block placing taking place after the "real" placement of block.

    More ideas? I'm confused :S
     
  4. Offline

    nisovin

    Are you cancelling the event?
     
  5. Offline

    Fauglir

    No, just created a new server from CraftBukkit 1.1-R3 (just downloaded) and in my plugin I'm using bukkit-1.1-R4-20120207.011601-34 . Does this have something to do with the malfunction?
     
  6. Offline

    nisovin

    Well, if you aren't cancelling the event, the server is probably setting it back to cobble after the event is done.
     
  7. Ahh, derp. You change the block, and then the BlockPlace event and code gets fired, and since you don't cancel that it changes the block to what the player is placing.
     
  8. Offline

    Fauglir

    Yep, that's it. If I try to cancel the event after setting type, the cobblestone block never places. By what println says, it looks like in server the block is made of stone, but in screen I can't see that. And what disturbs me is the first version of the code worked fine.
     
  9. Offline

    nisovin

    Make sure you cancel it, and try adding this line:

    event.getBlockReplacedState().setType(Material.STONE);
     
  10. Offline

    Fauglir

    Code:
            if (mat.compareTo(Material.COBBLESTONE) == 0 && plugin.getPlayerEnabled(player)) {
                //if (plugin.getTypePlugin(player) == 0)    //Free AutoStone
                    event.getBlockReplacedState().setType(Material.STONE);
                    event.setCancelled(true);
                    System.out.println(block.getType().name());
    With this I can manage to change cobblestone blocks to stone blocks automatically, but the block returns to my inventory because the event cancels (I suppose it's because of that). I think it's almost there :p
     
  11. Offline

    nisovin

    Okay, after doing some digging, I've discovered this is a bug in R3. Your original code will work fine on builds 1866+.
     
  12. Offline

    desht

    A rather hacky workaround would be to schedule a delayed task to replace the block with stone:
    Code:java
    1.  
    2. Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
    3. @Override
    4. public void run() {
    5. block.setType(Material.STONE);
    6. }
    7. });
    8.  
     
  13. Offline

    Fauglir

    It's fixed now, thanks ;)

    You can close the thread :p
     
Thread Status:
Not open for further replies.

Share This Page