Solved Get the block from SignChangeEvent

Discussion in 'Spigot Plugin Development' started by GnRDevelopment, Jul 24, 2018.

  1. I'm coding a plugin where a sign can only be placed on a chest. Is there a way to grab the block that the sign was placed on?

    Thanks!
     
  2. I don't think the SignChangeEvent fits your needs. Try using the BlockPlaceEvent and check if the block clicked is a chest.
     
    • Friendly Friendly x 1
  3. I switched from BlockPlaceEvent to SignChangeEvent because SignChangeEvent had things that BlockPlaceEvent doesn't have.
     
  4. Okay. Well, what you would do is "search" around where the sign is placed. Remember that with Location there's a #getBlock() method.
     
    • Friendly Friendly x 1
  5. I assume with 'placed on chest' you mean like 'attached to the chest'? And I assume you use the SignChangeEvent, because you only want to affect sign placement of signs with specific content? In that case, maybe try something like this:
    Identify whether the sign in question is one you want to react to by checking the content of the sign lines. If it is: Use the block from the SignChangeEvent, check if it is still a sign (something (ex. another plugin) might have removed the sign again in the meantime), check if is a wall sign (sign (post) and wall sign are different materials), get its BlockData, cast it to org.bukkit.block.data.Sign (which extends Rotatable), get the rotation (gives you a BlockFace), get the block relative to the sign block in the direction indicated by the rotation BlockFace, check if that block is a chest.
    If it isn't, remove the sign block manually (set to air).

    If you actually mean 'placed on top of a chest': Check if the block is a sign (post), get the block below, check if it's a chest.
     
    • Winner Winner x 1
    • Informative Informative x 1
  6. In my code, I already have it look for the content and react to it accordingly. Everything works fine except I can place the sign anywhere with the correct text and it will work. I just want it to only be on the face of chests. Not on top but attached like you said. Also, the only other plugin on my Server is Essentials. I've found some code but .getAttachedFace() doesn't seem to be recognized.

    EDIT: Here's my code so you can look at it:
    Code (Java):
    @SuppressWarnings("deprecation")
        @EventHandler
        public void onSignChange(SignChangeEvent e) {
            Sign sign = (Sign) e.getBlock().getState().getData();
            Block attached = e.getBlock().getRelative(sign.getAttachedFace());
            if (attached.getType() == Material.CHEST || attached.getType() == Material.CHEST) {
                String line1 = e.getLine(0);
                String line2 = e.getLine(1);
                String line3 = e.getLine(2);
                String line4 = e.getLine(3);
                if (e.getPlayer().hasPermission("sellchest.create") || (e.getPlayer().hasPermission("sellchest.*") || (e.getPlayer().isOp())) && ((line1.equalsIgnoreCase("[SellChest]") && (line2.equals(null) && (line3.equals(null) && (line4.equals(null))))))) {
                    e.setLine(0, ChatColor.translateAlternateColorCodes('&', Main.signtitle));
                    e.setLine(1, ChatColor.translateAlternateColorCodes('&', Main.line2));
                    e.setLine(2, ChatColor.translateAlternateColorCodes('&', Main.line3));
                    e.setLine(3, ChatColor.translateAlternateColorCodes('&', Main.line4));
                    e.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', Main.msgprefix + Main.signcreated));
                    } else {
                        e.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', Main.msgprefix + Main.noperms));
                        e.setCancelled(true);
            }
               
        }
       
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent e) {
            Player p = e.getPlayer();
           
            if (e.getAction() == Action.RIGHT_CLICK_BLOCK && (e.getClickedBlock().getState() instanceof Sign)) {
                Sign s = (Sign) e.getClickedBlock().getState();
                if (s.getLine(0).equalsIgnoreCase(ChatColor.translateAlternateColorCodes('&', Main.signtitle)) && (p.hasPermission("sellchest.use") || (p.hasPermission("sellchest.*")) || (p.isOp()))) {
                    p.sendMessage("It works!");
                    } else {
                        p.sendMessage(ChatColor.translateAlternateColorCodes('&', Main.msgprefix + Main.noperms));
     
  7. Well if the sign isn't a WALL_SIGN and it's attached to a chest, cancel the event.
     
    • Friendly Friendly x 1
  8. I've changed the code to only look for WALL_SIGN's but how would you recommend getting the block it's attached to?
     
  9. If I'm not wrong, you can no longer get the 'attached block face' like you attempted above in Bukkit 1.13. That's why I suggested, that you will have to use the new Sign BlockData API, get the sign's direction and derive the attached block by that.
     
    • Useful Useful x 2