[SOLVED] Opaque Block ?

Discussion in 'Plugin Development' started by rominos2, Nov 29, 2011.

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

    rominos2

    Hi,
    I'm searching a method to know if the block is not opaque like flowers or toches.

    The only way I've found for the moment is within spout but I don't know how to get a org.getspout.spoutapi.material.Block with a Bukkit Block

    Any ideas ?
    And better than that, any solutions ? ^^

    Thanks
     
  2. This should do it:
    Code:java
    1. ((org.getspout.spoutapi.material.Block) block).isOpaque();
     
  3. Offline

    xpansive

    Is there a way to do this without spout?
     
  4. Offline

    Baummann

    This could work:
    Code:
    public boolean isOpaqueBlock(Block block) {
         Block block2 = new Location(block.getWorld(), block.getX(), block.getY() + 1, block.getZ());
         block2.setType(Material.setType(Material.REDSTONE_REPEATER_OFF)); //Redstone repeaters can't stay on non-opaque blocks
         block2.getState().update(true); //Make the repeater check if it can stay
         Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
                  public void run() {
                         switch (block2.getType()) {
                         case Material.AIR: //If the repeater is gone, it means the block is not opaque
                                       return false;
                         default: //Else the block is opaque
                                       block2.setType(Material.AIR); //Remove the repeater
                                       block2.getState().update(true); //Optional Block Update
                                       return true;
                         }
                  }
         }, 1); //Wait 1 tick before executing the code
         return false;
    }
     
  5. Offline

    sorklin

    Aren't you calling bukkit methods from an aync thread, and isn't that a no-no?
     
  6. Offline

    Baummann

    You can't call Bukkit methods from a sync thread, but in an async thread you can.

    What do you exactly mean by no-no? That it always returns false?

    Code:
    public boolean test() {
        boolean test = true;
        if (!test)
             return false; //Returns false and exits out of the method
        else
             return true; //Returns true and exits out of the method
    return false; //Only returns this when test == null
    }
     
  7. Offline

    sorklin

    No-no means don't do it. Bukkit isn't thread safe, so you can only call bukkit methods from sync threads or the main thread. Async will crash your server, or corrupt your world (eventually).
     
  8. Offline

    Baummann

  9. Offline

    desht

    @Baummann I'm afraid your method (though cunning in concept) simply won't work. You're trying to return true or false from the Runnable run() method, which is void. And in any case, even if it was possible for run() to return something, it's being called in the future, and it doesn't make sense to take the return value of something that hasn't actually run yet and then return that value from your method.

    The only way to do this without Spout is to manually check for all the non-opaque block types. Ugly, but there you have it.
     
    Darkman2412 likes this.
  10. Offline

    rominos2

    @desht
    @r3Fuze
    You're right. That's ugly

    I can use Spout
    But how can I get a org.getspout.spoutapi.material.Block from a Bukkit Block
    Because I cannot cast.

    Code:
    java.lang.ClassCastException: org.getspout.spout.block.SpoutCraftBlock cannot be cast to org.getspout.spoutapi.material.Block
    
     
  11. Offline

    Baummann

    Code:
    public boolean isOpaqueBlock(Block block) {
        boolean opaque = false;
        Block block2 = new Location(block.getWorld(), block.getX(), block.getY() + 1, block.getZ());
        block2.setType(Material.setType(Material.REDSTONE_REPEATER_OFF)); //Redstone repeaters can't stay on non-opaque blocks
        block2.getState().update(true); //Make the repeater check if it can stay
        Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
                  public void run() {
                        switch (block2.getType()) {
                        case Material.AIR: //If the repeater is gone, it means the block is not opaque
                                      opaque = false;
                        default: //Else the block is opaque
                                      block2.setType(Material.AIR); //Remove the repeater
                                      block2.getState().update(true); //Optional Block Update
                                      opaque = true;
                        }
                  }
        }, 1); //Wait 1 tick before executing the code
        return opaque;
    }
    Edited to (probably) work.
     
  12. Nope, cause run() is executed one tick after the return of isOpaqueBlock, so isOpaqueBlock will always return false.
     
  13. Offline

    Afforess

    ((SpoutBlock)block).getBlockType()

    All bukkit blocks can be cast to a SpoutBlock. Check the javadocs for a full list of methods.
     
  14. Offline

    xpansive

    Okay guys here's the magical solution:
    world.getHandle().e(x, y, z)
    I'm pretty sure its isSolid not isOpaque though, so invert the output if you're checking for an opaque block.
     
  15. Offline

    rominos2

    @Afforess
    I was searching for a org.getspout.spoutapi.material.Block
    not a SpoutBlock

    @xpansive
    That's a good idea I'll test it right now

    EDIT :
    In fact is there a link between opaque and snowable (possibility of putting snow on it) ?
    How can I get if a block is snowable or not ?
     
  16. Offline

    bleachisback

    no, because opaque has to be final, in which case, you can't change it.[/CODE][/COLOR][/FONT][/quote]
     
  17. Offline

    Brain

    Perhaps you should bridle the horse from the other end.

    Code:
    public boolean isOpaqueBlock(Block block) {
         Block block2 = new Location(block.getWorld(), block.getX(), block.getY() + 1, block.getZ());
         block2.setType(Material.setType(Material.REDSTONE_REPEATER_OFF)); //Redstone repeaters can't stay on non-opaque blocks
         block2.getState().update(true); //Make the repeater check if it can stay
    
        switch (block2.getType()) {
            case Material.AIR: //If the repeater is gone, it means the block is not opaque
                return false;
            default: //Else the block is opaque
                final Future future = Bukkit.getServer().getScheduler().callSyncMethod(plugin, new Callable<Boolean>() {
                    public Boolean call() {
                        block2.setType(Material.AIR); //Remove the repeater
                        block2.getState().update(true); //Optional Block Update
                        return true;
                   }
                });
                return future.get();
         }
         return false;
    }
    This might need some fine-tuning bracket-wise (I'm not good at typing code in a variable-size font in a small text window), but it should make my point.
    You generate a synchronized call, get the future update and just wait for it to update. This is what the future.get() call without parameters does.

    You need to synchronize write access and you should make the synchronized part as small as possible. Reading is non-critical if you can live with the occasional wrong value caused by a concurrent update while you read which is rather unlikely if the immediate surrounding world is static.
    However if this code is executed from the main thread - that is you didn't create any threads of your own - you don't need the sync calls at all.

    Good luck!

    P.S. Just noticed the 3rd and 4th line might need some synchronization too. Not going to change the code now.
     
  18. Offline

    Afforess

  19. Offline

    rominos2

    @Afforess

    Thanks man

    @Others
    Thanks to but it's a little bit hard for something I want to schedule x100 / tick
     
  20. 100 times a tick?!?! Thats about 2000 times a second, you know.
     
  21. Offline

    rominos2

    I know.
    In fact the way I do it is functioning now
    I'll release it in my next Update if Seasons
     
Thread Status:
Not open for further replies.

Share This Page