Having Trouble with Breaking Blocks

Discussion in 'Spigot Plugin Development' started by floory565, Jun 7, 2016.

  1. floory565

    Moderator

    Hi all,

    I'm trying to create an event handler for when an arrow strikes a block, such that the block breaks. This is my code:

    Code (Java):

    @EventHandler
        public void onProjectileHit(ProjectileHitEvent e) {
           
            Bukkit.getServer().broadcastMessage("A projectile hit an object!");
           
            Entity projectile = e.getEntity();
           
            if(projectile instanceof Arrow) {
               
                Bukkit.getServer().broadcastMessage("The projectile was an arrow!");
               
                Location location = projectile.getLocation();
               
                Block block = location.getBlock();
               
                if(block.getType() == Material.GRASS) {
                   
                    Bukkit.getServer().broadcastMessage("The arrow struck a glass block!");
                   
                    block.setType(Material.AIR);
                   
                    Bukkit.getServer().broadcastMessage("The glass block was destroyed!");
                   
                }
               
            }
           
        }
     
    I've left my debugging messages in there intentionally - the first two work fine whenever I shoot a bow, but the last two (after testing whether the block is grass or not) do not show, even if shooting grass.

    I've also tested removing the "test grass" section and setting any block that gets struck by an arrow as AIR (ie. destroying it), but that does not work either.

    Any ideas? Thanks.
     
  2. Are you wanting the block to drop when broken?

    EDIT: Btw you have GRASS instead of GLASS

    EDIT2: nvm i realized you already said that
     
  3. floory565

    Moderator

    No I don't - I just want the block to break (preferably with the normal breaking animation - not the cracks, just the "particle poof" if you know what I mean).
     
  4. When the event fires, more often than not the projectile is not in the location of the block it hit.

    block.breakNaturally() will make the block break animation with the drop. Not sure if a BlockBreakEvent is called with that, so test that out. If its not, I suggest calling the event yourself and checking if any plugins cancelled it. That way you arent breaking protected blocks with arrows ;)
     
  5. floory565

    Moderator

    I've done a ProjectileHitEvent though - shouldn't the e.getProjectile().getLocation().getBlock() be the block that the arrow strikes?

    Edit: I've tried breakNaturally() but that didn't work.
     
  6. No. The collision of the arrow on the block is at the edge of the arrow. the location of the arrow is at it's center. the two are most often not in the same location when the event triggers. Example: When an arrow hits a tree, the arrow is in the air block next to the log it hit. etc.
     
  7. floory565

    Moderator

    Oh, that makes sense now. Do you know how I could go about getting the block at the tip of the arrow?
     
  8. Thats a very good question. Its been asked many many times before. Some answers are pretty good, some are not. Just google it up and see what you can find.

    Here's one of the oldest questions I could find from 2011: https://bukkit.org/threads/getting-block-hit-by-projectile-arrow.49071/
     
  9. I think you could get the direction of the arrow and then multiply it by like 0.1 then add it to the location of the arrow and that should be the block it's stuck to.
     
  10. This is one of those not so good answers (no offense). It answers the question 90% of the time. The other 10% of the time it will yield the wrong block/location. If an arrow hits the corner/edge of a block and not its center, a 0.1 distance from it's center could be a block it didnt hit.

    [​IMG]

    The best answer I've seen to date uses the BlockIterator like in the link I posted. No matter how much or how little a ray goes through a block, you can iterate through the blocks in order of the ray direction.