Opening a door?

Discussion in 'Plugin Development' started by Technius, Jan 24, 2012.

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

    Technius

    So I'm trying to open a door, and this is what I have so far:

    Note: The method is onPlayerInteract
    Code:java
    1.  
    2. Door d = (Door) event.getClickedBlock().getState().getData();
    3. if(!d.isOpen())
    4. {
    5. if(pickLockSuccess(event.getPlayer()))
    6. {
    7. d.setOpen(true);
    8. if(d.isTopHalf())((Door)event.getClickedBlock().getRelative(BlockFace.DOWN, 1).getState().getData()).setOpen(true);
    9. else ((Door)event.getClickedBlock().getRelative(BlockFace.UP, 1).getState().getData()).setOpen(true);
    10. if(event.isCancelled())event.setCancelled(false);
    11. event.getPlayer().sendMessage(ChatColor.GREEN + "Lockpicking success!");
    12. event.getClickedBlock().getState().update();
    13. }
    14. }
    15.  

    No exceptions and the message gets sent. But nothing happens. Is there anything wrong with this code?
     
  2. Offline

    AbeJ

    Why are you calling setCancelled(true) if the event is already cancelled?
     
  3. Offline

    Technius

    I fixed that, and put false. Can you please stay on topic? Why doesn't the door open?
     
  4. Offline

    bergerkiller

    Here's my two cents:
    Code:
        public static boolean isDoor(Material type) {
            return type == Material.WOODEN_DOOR || type == Material.IRON_DOOR;
        }
        public static void setBlock(Block mainblock, boolean toggled) {
            if (mainblock != null) {
                for (BlockFace face : Util.diamond) {
                    Block b = mainblock.getRelative(face);
                    Material type = b.getType();
                    if (type == Material.LEVER) {
                        if (Util.isAttached(b, mainblock)) {
                            Util.setLever(b, toggled);
                        }
                    } else if (type == Material.NOTE_BLOCK) {
                        if (toggled) {
                            ((NoteBlock) b.getState()).play();
                        }
                    } else if (type == Material.PISTON_STICKY_BASE || type == Material.PISTON_BASE) {
                        Util.setPiston(b, toggled);
                    } else if (Util.isDoor(type)) {
                        Door door = (Door) type.getNewData(b.getData());
                        if (toggled != door.isOpen()) {
                            door.setOpen(toggled);
                            Block above = b.getRelative(BlockFace.UP);
                            Block below = b.getRelative(BlockFace.DOWN);
                            if (Util.isDoor(above.getType())) {
                                b.setData(door.getData(), true);
                                door.setTopHalf(true);
                                above.setData(door.getData(), true);
                            } else if (Util.isDoor(below.getType())) {
                                door.setTopHalf(false);
                                below.setData(door.getData(), true);
                                door.setTopHalf(true);
                                b.setData(door.getData(), true);
                            }
                            b.getWorld().playEffect(b.getLocation(), Effect.DOOR_TOGGLE, 0);
                        }
                    } else if (type == Material.TRAP_DOOR) {
                        TrapDoor td = (TrapDoor) type.getNewData(b.getData());
                        if (td.isOpen() != toggled) {
                            byte data = (byte) (td.getData() ^ 4);
                            b.setData(data);
                            b.getWorld().playEffect(b.getLocation(), Effect.DOOR_TOGGLE, 0);
                        }
                    }
                }
            }
        }
    Note: code is from Redstone Mania, I use it to toggle all sorts of blocks.

    A bit more highlighted:
    Code:
                        Door door = (Door) type.getNewData(b.getData());
                        if (toggled != door.isOpen()) {
                            door.setOpen(toggled);
                            Block above = b.getRelative(BlockFace.UP);
                            Block below = b.getRelative(BlockFace.DOWN);
                            if (Util.isDoor(above.getType())) {
                                b.setData(door.getData(), true);
                                door.setTopHalf(true);
                                above.setData(door.getData(), true);
                            } else if (Util.isDoor(below.getType())) {
                                door.setTopHalf(false);
                                below.setData(door.getData(), true);
                                door.setTopHalf(true);
                                b.setData(door.getData(), true);
                            }
                            b.getWorld().playEffect(b.getLocation(), Effect.DOOR_TOGGLE, 0);
                        }
     
    Technius likes this.
  5. Offline

    AbeJ

    Because, by fixing things like that, you can make your code cleaner. That will make the issue easier to find.
    OT: Use bergerkiller's code.
     
  6. Offline

    Technius

    Thanks!
     
  7. Offline

    Nagetier

    Hey I found this topic because I'm trying to check if a door is open or not, I check PlayerInteractions and do a check if the clicked block is a door, this is working out very well, but when it comes to checking the door status it messes up.

    When the door is closed and I click the uper segment of the door and the door opens the output is that door.isOpen -> false the same happens wenn I close the door with clicking on the upper segment.

    When I click the lower segment of the door and it opens the output is the same door.isOpen-> false, when clicking the lower segment to close the door it tells me door.isOpen -> true!

    Bukkit only gets the state BEFORE my interaction, and somehow isn't able to check open/close in any way on the upper segment although it gets recognized as a door...

    This is my code so far:

    Code:java
    1.  
    2. @EventHandler
    3. public void onPlayerDoorOpen(PlayerInteractEvent event)
    4. {
    5. Action action = event.getAction();
    6. Block clicked = event.getClickedBlock();
    7.  
    8. //Left or Right click?
    9. if ((action == Action.RIGHT_CLICK_BLOCK) || (action == Action.LEFT_CLICK_BLOCK))
    10. {
    11. //Door Block?
    12. if(isDoor(clicked))
    13. {
    14. //Send Material to waterdoor function, no need to change over and over....
    15. Material btype = clicked.getType();
    16. Door door = (Door) btype.getNewData((clicked.getData()));
    17.  
    18. //Check if door is open
    19. if(door.isOpen() == true)
    20. {
    21. log.info("We got an open door here!");
    22. waterThroughDoor(door, clicked);
    23. }
    24. else
    25. {
    26. log.info("We got a closed door here!");
    27. }
    28. }
    29. else
    30. {
    31. log.info("Sorry, no door found!");
    32. }
    33. }
    34. else{ }
    35. }
    36.  


    This is the door checker

    Code:java
    1.  
    2. private boolean isDoor(Block clicked_block)
    3. {
    4. Material btype = clicked_block.getType();
    5. log.info(btype.toString() + " found as material!");
    6.  
    7. if((btype == Material.WOODEN_DOOR) || (btype == Material.IRON_DOOR_BLOCK))
    8. {
    9. return true;
    10. }
    11. else
    12. {
    13. return false;
    14. }
    15. }


    Where's the mistake? I already tried to update the block status over getting the location and afterwards getting the block at this location, same result...
     
  8. Offline

    Giant

    Does this issue happen on both the wooden AND the iron door? Or only the iron door? In case of the latter:
    You are using Material.IRON_DOOR_BLOCK and if I recall correctly, this one only contains 1 half of the door. You would be looking for: Material.IRON_DOOR.
     
  9. try adding debug staments, to see were it goes wrong
     
  10. Offline

    Nagetier

    When looking for IRON_DOOR the door doesn't get recognized at all, thats strange...
    The doors get recognized pretty well the problem is that after opening it the isOpen is returning me the previous state of the door, but I need the status of the door AFTER clicking it, just inverting the output wont help me because of iron doors not opening when right clicking...:oops:

    Never worked with debug statements so far, been used to C#, was way easier there, how do I manage this in Java?
     
  11. Offline

    Giant

    Just add a message at the point where you think it fails. If it fails there indeed the message should/shouldn't show :p
     
  12. Offline

    Wolvereness Bukkit Team Member

    Just an FYI, Door MaterialData is broken in 1.2.5. This is because doors now use relational multi-block data values.
     
  13. Offline

    Nagetier

    Thats what I did at the moment :D Good to know I did it right... it fails at checking if open or closed...

    Wolvereness, so how would I manage the whole checking thing then? How do I work with these relational multi block data values?
     
  14. Offline

    pure1

    do you get a error along the lines of
    Code:
    20:53:41 [SEVERE] Could not pass event PlayerInteractEvent to ZombieCraft
    org.bukkit.event.EventException
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:332)
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:477)
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:462)
        at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:177)
        at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(CraftEventFactory.java:147)
        at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:619)
        at net.minecraft.server.Packet15Place.handle(SourceFile:58)
        at net.minecraft.server.NetworkManager.b(NetworkManager.java:281)
        at net.minecraft.server.NetServerHandler.d(NetServerHandler.java:109)
        at net.minecraft.server.ServerConnection.b(SourceFile:35)
        at net.minecraft.server.DedicatedServerConnection.b(SourceFile:30)
        at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:583)
        at net.minecraft.server.DedicatedServer.q(DedicatedServer.java:212)
        at net.minecraft.server.MinecraftServer.p(MinecraftServer.java:476)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:408)
        at net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
    Caused by: java.lang.NullPointerException
        at me.pure1.zombiecraft.ZombieBlockListener.isSign(ZombieBlockListener.java:88)
        at me.pure1.zombiecraft.ZombieBlockListener.onPlayerInteract(ZombieBlockListener.java:65)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:330)
        ... 16 more
    >
    
    p.s. just experimenting with your code, or pieces of it, to get an idea of block checking and opening doors with signs, otherwise my head will explode.

    --edit--
    just realised last post was in april, you've probably solved this...
     
Thread Status:
Not open for further replies.

Share This Page