Explosion Block Regen

Discussion in 'Plugin Development' started by BurnBlader, Jul 6, 2013.

Thread Status:
Not open for further replies.
  1. I have made an explosion block regen feature, which works well, but ever since I tried to limit the blocks that can explode it hasn't been working.

    Code:
    @EventHandler
        public void onExplode(final EntityExplodeEvent event) {
            
            final List<Block> toputback = new ArrayList<Block>();
            
            List<Block> destroyed = event.blockList();
            Iterator<Block> it = destroyed.iterator();
            while (it.hasNext()) {
            Block block = it.next();
             
            if(!(block.getType() == Material.GRASS) || !(block.getType() == Material.DIRT))
                it.remove();
            else
                toputback.add(block);
            }
            
            i = toputback.size();
            
            p.getServer().getScheduler().scheduleSyncRepeatingTask(p, new Runnable() {
    
                @Override
                public void run() {
                    toputback.get(i).setType(Material.GRASS);
                    i--;
                }
                
            }, 0L, 5L);
        }
    
    It just doesn't explode anything and I'm getting spammed with errors.
    Code:
    17:34:23 [WARNING] [PluginName] Task #65 for [PluginName] v2.0 generated an exception
    java.lang.ArrayIndexOutOfBoundsException
    
    I was wondering if anyone could help me out with my problem.
     
  2. Offline

    perwin

    Hi,
    the ArrayIndexOutOfBoundsException is thrown because you are trying to get a block with index equal to the size of the List toputback, but index of the last item in List is always size of list - 1.
    You can simply fix that exception by changing
    Code:java
    1. i = toputback.size();
    to
    Code:java
    1. i = toputback.size() - 1;
    But you have many more mistakes in your code.
    I wrote this code, much simplier, which should be working fine:
    Code:java
    1.  
    2. @EventHandler
    3. public void onEntityExplode(final EntityExplodeEvent event) {
    4. final List<Block> destroyed = event.blockList();
    5.  
    6. plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
    7. @Override
    8. public void run() {
    9. for(Block block : destroyed) {
    10. if(block.getType() != Material.DIRT && block.getType() != Material.GRASS) {
    11. block.setType(Material.GRASS); // Changes every exploded block which isn't DIRT or GRASS to GRASS
    12. }
    13. }
    14. }
    15. }, 5L);
    16. }
    17.  
     
  3. Thanks for that, but I want the blocks to come back 1 by 1. Not just altogether.
     
  4. Offline

    perwin

    Ok, so we can use recursive method:
    Code:java
    1.  
    2. @EventHandler
    3. public void onEntityExplode(final EntityExplodeEvent event) {
    4. List < Block > d = event.blockList();
    5. Iterator < Block > i = d.iterator();
    6. while (i.hasNext()) {
    7. Block block = i.next();
    8. if (block.getType() == Material.DIRT || block.getType() == Material.GRASS) {
    9. i.remove();
    10. }
    11. }
    12. regen(d);
    13. }
    14. private void regen(final List<Block> d) {
    15. plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
    16. @Override
    17. public void run() {
    18. Block block = d.get(0);
    19. block.setType(Material.GRASS);
    20. d.remove(0);
    21. if (d.size() != 0) {
    22. regen(d); // Recursively calls itself until no blocks are remaining
    23. }
    24. }
    25. }, 20L); // Every second one block
    26. }
    27.  
    28.  
     
Thread Status:
Not open for further replies.

Share This Page