Solved !Signs == Material.Sign?

Discussion in 'Plugin Development' started by tuskiomi, May 22, 2013.

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

    tuskiomi

    Hello all, I'm new to the forum and I have been getting along on other people's forum posts and the bukkit JD. :) good stuff :).
    so in my code I have this
    Code:
    public void onPlayerInteractBlock(PlayerInteractEvent evt) {
            if (evt.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
                Player p = evt.getPlayer();
                Block B = p.getTargetBlock(null, 3);
                            if (B.getType() == Material.SIGN || B.getType() == Material.SIGN_POST || B.getType() == Material.WALL_SIGN) {
                                  //super secret stuff in here
                            }else{
                            mainclass.log.info("That isn't a sign. That is a "+B.toString());
                            }
    when a sign is clicke the console produces:
    That is a CraftBlock{chunk=CraftChunk{x=5z=-4},x=95,y=63,z=-61,type=WALL_SIGN,data=3}
    Why won't IF statement accept the material?
    all my imports are bukkit imports.
    what can i do to improve of fix my code?
     
  2. Offline

    Pink__Slime

    Change "B.getType() == Material.SIGN" to "B == Block.SIGN"
     
  3. Offline

    MrTwiggy

    First off, you can do

    Block B = event.getBlock();

    to get the block that was clicked.

    Second, I believe you can do

    if (B.getState() instanceof Sign)
    {

    }
     
  4. Offline

    Rockett8855

    Code:java
    1.  
    2. public void onSignClick(PlayerInteractEvent e) {
    3. Player p = e.getPlayer();
    4. if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
    5. Block b = e.getClickedBlock();
    6. if (b.getType() == Material.WALL_SIGN || b.getType() == Material.SIGN_POST) {
    7. Sign s = (Sign) b;
    8. //You can cast to a sign because you know the only blocks that got this far in the if statements are signs.
    9. // Super Secret Code :)
    10. } else {
    11. // Whatever happens if they clicked something other than a sign :)
    12. }
    13. }
    14. }
    15.  


    This is how I do it.
     
  5. Offline

    tuskiomi

    Okay, change to getClickedblock() and block.Sign. thanks marking solved.
     
  6. Offline

    desht

    Not recommended. Block.getState() is a fairly expensive call; you should only use it after confirming that the block is of the expected type with Block.getType() (in this case, a SIGN_POST or WALL_SIGN - but not a SIGN, which is an item, not a block).
     
  7. Offline

    Minnymin3

    Its slightly less expensive than calling 3 getType methods. Call one getType method and then check if it is equal to those materials for least lag. But block.getState() barely takes up any resources and wont cause problems except on servers with over 200 people all right clicking at the same time but by that point the server hardware should be able to keep up with 200 getState() methods per second.
     
  8. Offline

    tuskiomi

    okay, so now i have the sign working correctly thanks to you guys, but a different problem has arose, and since it is not related to this, i'm putting it in a different thread
     
  9. Offline

    desht

    It most certainly is not. A getState() call will lead to the instantiation of a MaterialData subclass via reflection. In what way would that be less expensive than 3 getType() methods (of course in this case only 2 calls to getType() are needed), a method which does one array indexing operation and returns that value?

    That's a pretty unfortunate attitude to take.
     
  10. Offline

    ZachBora

    :eek: I got some code to rewrite

    How would you replace this :

    Code:java
    1.  
    2. BlockState state = block.getState();
    3.  
    4. if(state instanceof InventoryHolder)
    5. {
    6. [...]
    7. }
    8.  
    9. if(state instanceof Jukebox)
    10. {
    11. [...]
    12. }
    13.  
     
  11. Offline

    desht

    A more general check for an InventoryHolder is a bit more problematic; you'd need to check the block's type for any block which could be an inventory holder. Which is fairly long-winded (and needs revisiting after any major Minecraft release, when new inventory holders get added, like hoppers/droppers/etc.). So it's a trade-off between performance (checking blocking type) and brevity/maintainability (checking the blockstate). You also need to take into account how often that check will be done. If it's frequent (e.g. every single player interact event), that's more incentive to make it as light as possible on CPU.

    For the specific Jukebox check, it's trivial - just check if the block's type is Material.JUKEBOX.
     
  12. Offline

    ZachBora

    desht I am checking if the block is an inventory holder while looping through a large "cuboid". If it's a container, I clear it's inventory. This is to prevent a million items dropping on the ground. But it did slow down the process once I started clearing them this way. I think I'll change it to checktypes, even if it means adding types after updates.
     
Thread Status:
Not open for further replies.

Share This Page