Capturing button events

Discussion in 'Plugin Development' started by torpkev, Nov 26, 2018.

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

    torpkev

    I'd like to prevent a user from clicking on a button/lever/pressure plate etc. and was planning on using the following:

    Code:
        public void onPlayerInteract(PlayerInteractEvent event) {
            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                Block clicked = event.getClickedBlock();
                if (clicked.getType() == Material.STONE_BUTTON) {
                    // do something
                }
            }
        }
    1) Is there a way to see if its any kind of button instead of individually (and pressure plates, levers etc.)
    2) Is there a way to prevent the button firing if shot by an arrow?
    - For example, if I have an oak button, with the above code I can use event.setCancelled(true) to stop the button event firing - however, if I shoot the button, it activates. I never actually interact with it, but my arrow does.
     
  2. Offline

    The_Spaceman

    1: if (clicked.getType().name().endsWith("_BUTTON") || clicked.getType().name().endsWith("_PRESSURE_PLATE")) {}
    2: I have no idea, maybe EntityInteractEvent?
     
  3. Offline

    torpkev

    1. I was hoping for something a bit more set in stone.. if there was an instance for them.. so like.. Entity has Creature.. and that has Monster etc. something like that. If not, I'll just go ahead and group them up in a list of my own I suppose.

    2. EntityInteractEvent isn't firing when I shoot an arrow - I'm currently playing with the ProjectileHitEvent and then pulling the block - saving it and then in the BlockRedstoneEvent trying to pull the same block and see if the current changes.. but it isn't quite working yet
     
  4. Offline

    The_Spaceman

    Block b = null/*insert block here*/;
    if (b.getBlockData() instanceof Switch || b.getBlockData() instanceof ) {
    //block is a 'WoodButton', 'StoneButton' and 'Lever'
    }
    1 im not sure about pressure plates, you can check with CraftPressurePlateBinary, but that is in a package what will change every update... you can mess around with this, I think checking with org.bukkit.block.data.Powerable will help you a lot.

    2 never used it, I have no idea, it sounds like it should work
     
  5. Offline

    torpkev

    I got this working, though in probably some of the most inefficient coding possible - pointers are welcome. I suspect the BlockRedstoneEvent will fire like crazy if any clocks are being used, which would be no good. I will likely need to put a check on entries in my hashmap and just not do anything if its blank. Again.. I'd appreciate feedback on that.. I can't have the plugin killing the server if someone is running a clock.

    Anyway.. here is what I'm doing:

    In the ProjectileHitEvent I'm recording any time an arrow hits a block, saving the block and a timestamp to a hashmap. This is to allow for storing the block and the timestamp it was placed there.

    Then in the BlockRedstoneEvent I'm getting the surrounding blocks (the event doesn't fire against the power source, only the blocks touching it)

    I had originally used a List<Block> entry and then did the cleanup in the BlockRedstoneEvent but if I collect the arrow from the button the circuit activates if cleanup is done too early. Using the hashmap with the timestamp allows me to just remove any entries with timestamp > x seconds (I figure cleanup once a minute should be fairly painless).

    I'm creating a couple of strings for location, one for the hit block and one for the block i'm interrogating - I did try using Location fields but they never matched, not sure if its pitch/yaw etc. that was messing me up.

    If the location strings match, I'm then simply just killing the current.

    Thoughts?

    Code:
        @EventHandler(priority = EventPriority.HIGH)
        public void onProjectileHit(ProjectileHitEvent evt) {
            if (evt.getHitBlock() != null)
            {
                Block b = evt.getHitBlock();
                // Save any block hit with an arrow to my hashmap (Main: public static HashMap<Block, Timestamp> ArrowBlock = new HashMap<Block, Timestamp>();)
                // Saving to a hashmap rather than a list so I can save the timestamp with it - this will allow cleanup
                Main.getInstance();
                Main.ArrowBlock.put(b, new Timestamp(System.currentTimeMillis()));
            }  
        }
        @EventHandler
        public void onBlockRedstone(BlockRedstoneEvent evt)
        {
            Block b = evt.getBlock(); // Get event block  
            // Get the surrounding blocks
            for (int x = -1; x <= 1; x++) {
                for (int z = -1; z <= 1; z++) {
                    for (int y = -1; y <= 1; y++) {
                        if (x == 0 && y == 0 && z == 0) {
                            continue;
                        }
                        Block w = b.getWorld().getBlockAt(b.getX() + x, b.getY() + y, b.getZ() + z);
                        for (Block q : Main.ArrowBlock.keySet()){
                            // for each surround block, check my hashmap for this block
                            // convert the location to a string - checking for location being the same didn't work - perhaps yaw/pitch etc.?
                            String loc1 = w.getLocation().getWorld() + "|" + Integer.toString(w.getLocation().getBlockX()) + "|" + Integer.toString(w.getLocation().getBlockY()) + "|" + Integer.toString(w.getLocation().getBlockZ());
                            String loc2 = q.getLocation().getWorld() + "|" + Integer.toString(q.getLocation().getBlockX()) + "|" + Integer.toString(q.getLocation().getBlockY()) + "|" + Integer.toString(q.getLocation().getBlockZ());
                            if (loc1.equals(loc2))
                            {
                                evt.setNewCurrent(0); // Setting the current back to 0
                            }
                        }
                    }
                }
            }
            // Not doing cleanup here - if I collect the arrow, it activates the circuit and without my entry still there it clears it
        }
     
Thread Status:
Not open for further replies.

Share This Page