Solved Check if player right clicked a block that he/she can interact with

Discussion in 'Spigot Plugin Development' started by John55223, Jun 27, 2016.

  1. I am working with the PlayerInteractEvent, more specifically checking if a player right clicked a block. I want to know if the block he right clicked is something he can interact with (chest, furnace, gate etc). in the most efficient manner. (Obviously I can make a list of all the materials that are interactable, but that is very time consuming and there has to be a better way). If anyone knows of a way to do this, plz lemme know :D
     
  2. It's definitely good to search for simpler solutions. In this case, though, I do not see one. I did a little benchmarking test wherein I ran your operation 1,000,000 times using a hard-coded list of openable blocks:

    Code (Text):
    public class CommandTest extends InGameCommandExecutor {

        public CommandTest() {
            super(0, 0, Perm.ALL);
        }
       
        // I may have forgotten some
        private final Material[] openable = {Material.CHEST, Material.ENDER_CHEST, Material.BREWING_STAND, Material.HOPPER, Material.DISPENSER, Material.FURNACE, Material.BURNING_FURNACE, Material.TRAPPED_CHEST, Material.ENCHANTMENT_TABLE, Material.WORKBENCH};

        @Override
        public void onCommand(Player player, String[] args) {
           
            long start = System.currentTimeMillis();
            Block b = player.getLocation().getBlock();
           
            for (int i = 0; i < 1000000; i++) {
                boolean isOpenable = Arrays.asList(openable).contains(b.getType());
            }
           
            System.out.println(System.currentTimeMillis() - start);
        }
    }
    For me, this took 50-130ms to execute. Think of that -- a million block checks, in less time than it takes some people to ping a server. So as far as efficiency is concerned, the goal here is to make the code easier to read, write, and modify. Speed of execution is not an issue.
     
  3. Thanks for taking the time to run this. Perhaps efficiency wasn't the appropriate word for this scenario, but I did mean in terms of writing the code quickly and cleanly. I guess I will just create a list of all the materials that are interactable (unfortunately includes all doors trapdoors etc). Thanks for your time :D

    EDIT:
    Incase I can save someone else some time:
    Code (Text):

    private static List<Material> interactables = Arrays.asList(
                Material.ACACIA_DOOR,
                Material.ACACIA_FENCE_GATE,
                Material.ANVIL,
                Material.BEACON,
                Material.BED,
                Material.BIRCH_DOOR,
                Material.BIRCH_FENCE_GATE,
                Material.BOAT,
                Material.BOAT_ACACIA,
                Material.BOAT_BIRCH,
                Material.BOAT_DARK_OAK,
                Material.BOAT_JUNGLE,
                Material.BOAT_SPRUCE,
                Material.BREWING_STAND,
                Material.COMMAND,
                Material.CHEST,
                Material.DARK_OAK_DOOR,
                Material.DARK_OAK_FENCE_GATE,
                Material.DAYLIGHT_DETECTOR,
                Material.DAYLIGHT_DETECTOR_INVERTED,
                Material.DISPENSER,
                Material.DROPPER,
                Material.ENCHANTMENT_TABLE,
                Material.ENDER_CHEST,
                Material.FENCE_GATE,
                Material.FURNACE,
                Material.HOPPER,
                Material.HOPPER_MINECART,
                Material.ITEM_FRAME,
                Material.JUNGLE_DOOR,
                Material.JUNGLE_FENCE_GATE,
                Material.LEVER,
                Material.MINECART,
                Material.NOTE_BLOCK,
                Material.POWERED_MINECART,
                Material.REDSTONE_COMPARATOR,
                Material.REDSTONE_COMPARATOR_OFF,
                Material.REDSTONE_COMPARATOR_ON,
                Material.SIGN,
                Material.SIGN_POST,
                Material.STORAGE_MINECART,
                Material.TRAP_DOOR,
                Material.TRAPPED_CHEST,
                Material.WALL_SIGN,
                Material.WOOD_BUTTON,
                Material.WOOD_DOOR);
     
     
    #3 John55223, Jun 28, 2016
    Last edited: Jun 28, 2016
    • Like Like x 3
    • Informative Informative x 1
    • Useful Useful x 1