Solved Improper Sign Detection

Discussion in 'Spigot Plugin Development' started by NoEffort, Jun 29, 2018.

Thread Status:
Not open for further replies.
  1. So I've come across an issue where (with the method I'm using), the main block that the sign should be connected to will not always detect that it's connected to it. However, sometimes it will detect a sign that is connected to an adjacent block and not the main one. I've made a diagram below.
    [​IMG]
    Green: The Sign is Detected.
    Red: The Sign is NOT Detected.

    As of right now, the green face is to the east, specifically. It will only detect the sign properly when on the east face. I'm not sure why.

    Useful code:
    Code (Java):
    //Gets all possible Block Faces
    final BlockFace[] BLOCKFACE = { BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST };
           
    public void isAttatched(Block block) {
        for(BlockFace face : BLOCKFACE) {
            Block ifSign = block.getRelative(face);
            if(ifSign != null && ifSign.getType() == Material.WALL_SIGN) {
                Sign sign = (Sign) ifSign.getState();
                //More Code Here
            }
        }
    }

    I'm still not too sure why this is happening, or what I should go about changing.
     
  2. In your example, what is your block you are testing? The sign or the chest?
     
  3. Block block is being converted to a chest. I find the location of the chest, then detect if there is a sign on the chest.
     
  4. 100% Raw Code: (Warning, Explict Language)
    Code (Java):
    package me.noeffort.extendedchests.util;

    import java.util.Set;

    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.block.Chest;
    import org.bukkit.block.Sign;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.Inventory;

    import me.noeffort.extendedchests.Main;
    import me.noeffort.extendedchests.Messages;
    import me.noeffort.extendedchests.util.config.PlayerConfig;
    import me.noeffort.extendedchests.util.config.RangeConfig;

    public class PlayerClick implements Listener {
       
        private static RangeConfig rangeConfig;
        private static PlayerConfig playerConfig;
       
        //Initiating the Main class
        Main plugin;
       
        //Constructor
        public PlayerClick(Main instance) {
            this.plugin = instance;
        }
       
        //Ye old EventHandler
        @EventHandler
        public void onRightClickAir(PlayerInteractEvent event){
           
            rangeConfig = new RangeConfig(plugin) ;
            playerConfig = new PlayerConfig(plugin);
           
            //Gets all possible Block Faces
            final BlockFace[] BLOCKFACE = { BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST };
           
            //Gets the player
            Player player = (Player) event.getPlayer();
           
            //Gets the action (Left-Clicking)
            if (event.getAction() == Action.RIGHT_CLICK_AIR) {
               
                //Makes sure the player is using a certain item.
                if(!event.getItem().isSimilar(Main.getChestItem())) {
                    return;
                }
               
                rangeConfig.saveRangeConfig();
                rangeConfig.reloadRangeConfig();
               
                //Defines the max range
                int max = 100;
               
                //Defines the "openable" range
                int range = rangeConfig.getRangeConfig().getInt("baseRange");
               
                if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                    if(true) {
                        range = 5;
                    }
                }
               
                //Mutltiplier used later for the "openable" range
                float rangeMultiplier = 1.0F;
               
                //Creates a list of blocks in the player's sight
                java.util.List<Block> blocks = player.getLineOfSight((Set<Material>) null, max);
               
                //Loops through the list (blocks) to find a chest
                for (int i = 0; i < blocks.size(); i++){
                    //Found it
                    if (blocks.get(i).getType() == Material.CHEST) {
                        //Gets the block; defines as block
                        Block block = blocks.get(i);
                        //Gets the state of the chest
                        Chest chest = (Chest) block.getState();
                        //Defines the inventory of the chest (inv)
                        Inventory inv = chest.getBlockInventory();
                       
                        for(BlockFace face : BLOCKFACE) {
                            Block ifSign = block.getRelative(face);
                            if(ifSign != null && ifSign.getType() == Material.WALL_SIGN) {
                                Sign sign = (Sign) ifSign.getState();
                                if(sign.getLines().length > 0 && sign.getLines()[1].contains("[Extended]")) {
                                    if(!sign.getLine(3).isEmpty()) {
                                        sign.setLine(0, ChatColor.GREEN + "Generated");
                                        sign.setLine(2, ChatColor.RED + player.getName());
                                        sign.update();
                                    } else {
                                        player.sendMessage(MessageUtil.translate(Messages.invalidChest));
                                        sign.setLine(0, "");
                                        sign.setLine(1, "");
                                        sign.setLine(2, "");
                                        sign.setLine(3, "");
                                        sign.update();
                                        return;
                                    }
                                   
                                    int length = player.getName().length();
                                   
                                    if(!sign.getLine(2).replaceAll("(?i)\u00A7[0-F]", "").equals(player.getName().substring(0, length))) {
                                        event.setCancelled(true);
                                        break;
                                    } else {
                                        playerConfig.getPlayerConfigFile();
                                        playerConfig.getPlayerConfig().set("chests." + player.getName() + "." + player.getWorld().getName() + "." + sign.getLine(3) + ".x", block.getLocation().getBlockX());
                                        playerConfig.getPlayerConfig().set("chests." + player.getName() + "." + player.getWorld().getName() + "." + sign.getLine(3) + ".y", block.getLocation().getBlockY());
                                        playerConfig.getPlayerConfig().set("chests." + player.getName() + "." + player.getWorld().getName() + "."  + sign.getLine(3) + ".z", block.getLocation().getBlockZ());
                                        playerConfig.savePlayerConfig();
                                        playerConfig.reloadPlayerConfig();
                                       
                                    }
                                   
                                   
                                    //Gets the block's location
                                    Location blockLocation = blocks.get(i).getLocation();
                                    //Gets the player's location
                                    Location playerLocation = player.getLocation();
                                   
                                    //New location on the block below the chest
                                    Location newBlock = blockLocation.clone();
                                    newBlock.subtract(0, 1, 0);
                                   
                                    //Defining the block below the chest
                                    Block belowBlock = newBlock.getWorld().getBlockAt(newBlock);
                                   
                                    //Switches through the block types of belowBlock
                                    switch(belowBlock.getType()){
                                    case IRON_BLOCK:
                                        rangeMultiplier = (float) rangeConfig.getRangeConfig().getInt("rangeMultiplier.iron");
                                        if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                                            if(true) {
                                                rangeMultiplier = 1.5F;
                                            }
                                        }
                                        break;
                                    case GOLD_BLOCK:
                                        rangeMultiplier = (float) rangeConfig.getRangeConfig().getInt("rangeMultiplier.gold");
                                        if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                                            if(true) {
                                                rangeMultiplier = 2.0F;
                                            }
                                        }
                                        break;
                                    case DIAMOND_BLOCK:
                                        rangeMultiplier = (float) rangeConfig.getRangeConfig().getInt("rangeMultiplier.diamond");
                                        if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                                            if(true) {
                                                rangeMultiplier = 2.5F;
                                            }
                                        }
                                        break;
                                    case EMERALD_BLOCK:
                                        rangeMultiplier = (float) rangeConfig.getRangeConfig().getInt("rangeMultiplier.emerald");
                                        if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                                            if(true) {
                                                rangeMultiplier = 3.0F;
                                            }
                                        }
                                        break;
                                    default:
                                        rangeMultiplier = (float) rangeConfig.getRangeConfig().getInt("rangeMultiplier.default");
                                        if(rangeConfig.getRangeConfig().getBoolean("useDefaults")) {
                                            if(true) {
                                                rangeMultiplier = 1.0F;
                                            }
                                        }
                                        break;
                                    }
                                   
                                    //Does many maths
                                    int processed = (int) ((float)range * rangeMultiplier);
                                   
                                    //Determines if the player is within the block's range
                                    if(blockLocation.distance(playerLocation) < processed){
                                        //Opens the inventory
                                        player.openInventory(inv);
                                    }
                                    break;
                                }
                            } else {
                                event.setCancelled(true);
                                return;
                            }
                        }
                    }
                    //Fuck air
                    else if(blocks.get(i).getType() == Material.AIR){
                        continue;
                    } else {
                        break;
                    }  
                }
            }
        }
    }
    //What a nerd
     
  5. [​IMG]
    Where's the confused rating when u need it
     
  6. What are you confused about? The Language Warning? I put some bad words in those comments.
     
  7. I'm not really sure what you're asking, but I think you want to be able to know if the sign is actually attached or not. Here is some test code that checks for that:

    Code (Java):

    @EventHandler
    public void on(PlayerInteractEvent event) {
        Block block = event.getClickedBlock();
        if (block == null || block.getType() != Material.CHEST) {
            return;
        }
        isAttatched(block);
    }

    public void isAttatched(Block block) {
        for (BlockFace face : BLOCKFACE) {
            Block relative = block.getRelative(face);
            if (relative == null || relative.getType() != Material.WALL_SIGN) {
                continue; // not a sign
            }
            BlockState state = relative.getState();
            MaterialData data = state.getData();
            if (!(data instanceof org.bukkit.material.Sign)) {
                continue; // not a sign. wat?
            }
            org.bukkit.block.Sign sign = (org.bukkit.block.Sign) state;
            BlockFace attached = ((org.bukkit.material.Sign) data).getAttachedFace();
            if (!attached.equals(face.getOppositeFace())) {
                // not really attached (attached to other block)
                sign.setLine(0, "NOT Attached");
            } else {
                // attached to chest
                sign.setLine(0, "Attached");
            }
            sign.setLine(1, attached.toString());
            sign.update();
        }
    }
     
    Screenshot:
    [​IMG]
     
  8. Looks like I just had to flip through the possibilities a little more, and block out all of the unwanted things first. Works like a charm!
     
Thread Status:
Not open for further replies.