Removing blocks in front of a flying arrow

Discussion in 'Plugin Development' started by letsgo00, Jul 27, 2015.

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

    letsgo00

    I'm writing a plugin where I have to remove a block in front of a flying arrow. Can someone give me some code examples.
     
    Last edited: Jul 28, 2015
  2. Offline

    MCMatters

    ProjectileHitEvent
     
  3. Offline

    letsgo00

    @MCMatters With ProjectileHitEvent I can't get the hit block
     
  4. use e.getEntity().getLocation.getBlock()
     
  5. Offline

    Gater12

  6. Offline

    letsgo00

    @Gater12 with a flying arrow this does not work. The arrow stops in the blocks.
     
  7. @letsgo00
    Put a repeating task that runs each tick, when the entity died you cancel the task. Each time you get the next location by adding the arrow's velocity to it's location and set that block to air.
     
    DoggyCode™ and letsgo00 like this.
  8. Offline

    letsgo00

    @megamichiel is this correct?
    Code:
    private void removeBlock(){
            Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() {
               
                @Override
                public void run() {
                    for(Arrow a : arrows){
                        if(a.isDead() || a.getLocation().getBlockY() <= 0){
                            arrows.remove(a);
                        }
                        Location l = a.getLocation();
                        Block hitBlock = l.add(a.getVelocity()).getBlock();
                       
                       
                        if (hitBlock.getType() == Material.ICE || hitBlock.getType() == Material.PACKED_ICE) {
                            hitBlock.setType(Material.AIR);
                        }
                    }
                   
                }
            }, 0, 1);
        }
     
  9. Offline

    DoggyCode™

  10. @letsgo00
    Almost :p, you remove the arrow from the list, but because it's in a for loop, it will throw a ConcurrentModificationException. Change the beginning part to this:
    Code:
    Iterator<Arrow> it = arrows.iterator(); //Create a new iterator
    while(it.hasNext()) { //
      Arrow a = it.next(); //Get the next arrow
      if(a.isDead() || a.getLocation().getBlockY() <= 0) {
        it.remove(); //If you call a normal List#remove it will throw a CME, because a 'for' loop creates a new iterator instance, but when you suddenly remove an item from the list the iterator does not like that.
      }
     
    letsgo00 likes this.
  11. Offline

    letsgo00

    @megamichiel It's still not braking all the blocks. When it brakes the first block then it stops and falls.
    Here is the code:
    Code:
    private void removeBlock(){
            Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new Runnable() {
               
                @Override
                public void run() {
                    Iterator<Arrow> it = arrows.iterator();
                    while(it.hasNext()) {
                      Arrow a = it.next();
                        if(a.isDead() || a.getLocation().getBlockY() <= 0){
                            arrows.remove(a);
                        }
                        Location l = a.getLocation();
                        Block hitBlock = l.add(a.getVelocity()).getBlock();
                       
                       
                        if (hitBlock.getType() == Material.ICE || hitBlock.getType() == Material.PACKED_ICE) {
                            hitBlock.setType(Material.AIR);
                        }
                    }
                   
                }
            }, 0, 1);
        }
     
Thread Status:
Not open for further replies.

Share This Page