Solved Regenerating explosions problem

Discussion in 'Plugin Development' started by Jordymt, Nov 20, 2013.

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

    Jordymt

    Today I wanted to create something cool so I came up with the idea of making a little plugin with my own bombs and guns, the guns are no problem, but the bombs are.

    When I create an explosion with my bomb it'll work, but I want to restore the broken blocks during the explosion, so I came up with a Runnable that should do it's work properly, but it doesn't.

    This is the code of the EventHandler(need more? just ask):
    Code:java
    1. @EventHandler
    2. public void onExplode(EntityExplodeEvent e) {
    3. if(e.getLocation().getBlock() != null) {
    4. final BlockState old = e.getLocation().getBlock().getState();
    5. new BukkitRunnable() {
    6. @Override
    7. public void run() {
    8. old.update(true);
    9. }
    10. }.runTaskLater (this.plugin, 60L);
    11. }
    12. }


    Could anyone help me out?
    Jordy
     
  2. Offline

    L33m4n123

    What is not working? Any Errors?
     
    Jordymt likes this.
  3. Offline

    Jordymt


    No errors, but it doesn't regenerate the damaged blocks, not even one of them.
     
  4. Offline

    L33m4n123

    You registered the event?^^
     
  5. Offline

    blablubbabc

    You are only restoring the center block of the explosion (which likly is an air block).
    With event.blockList() you get a list of all destroyed blocks. You have to store those block's states and restore them later.

    However, this will only rollback the blocks material and data value and won't work that well currently to rollback TileEntity data (like sign text or or chest contents,.. ) due to an bug: ticket about it
     
    Jordymt likes this.
  6. Offline

    Jordymt



    Code:java
    1. @EventHandler
    2. public void onExplode(EntityExplodeEvent e) {
    3. if(e.getLocation().getBlock() != null) {
    4. Block explosion = (Block) e.blockList();
    5. final BlockState old = explosion.getState();
    6.  
    7. new BukkitRunnable() {
    8. @Override
    9. public void run() {
    10. old.update(true);
    11. Bukkit.broadcastMessage("Done :D");
    12. }
    13. }.runTaskLater (this.plugin, 60L);
    14. }
    15. }


    That won't work either, the part about sign's won't matter to me, don't need them.
     
  7. Offline

    XvBaseballkidvX

    You need to use a "for" loop and get all the blocks in the event.blockList().
    Code:java
    1. for(Block block: event.blockList()){
    2. //Your Code
    3. //
    4. //I suggest getting all the blocks locations and material types!
    5. //Also set the blocks to air so they don't create drops.
    6. }
    7.  


    If you are confused just tag me :p
     
    Jordymt likes this.
  8. Offline

    blablubbabc

    The EntityExplodeEvent has a .setYield(..) method which, according to the javadocs, can be used to stop item drops.
    Though, the last time I tested it, i think it didn't work that well..
     
    Jordymt likes this.
  9. Offline

    Jordymt



    [​IMG]

    I get these erros, line 70 is the one with Block explosion...
    My code now:

    Code:java
    1. @EventHandler
    2. public void onExplode(EntityExplodeEvent e) {
    3. for(Block block: e.blockList()){
    4. Block explosion = (Block) e.blockList();
    5. final BlockState old = explosion.getState();
    6.  
    7. new BukkitRunnable() {
    8. @Override
    9. public void run() {
    10. old.update(true);
    11. Bukkit.broadcastMessage("Done :D");
    12. }
    13. }.runTaskLater (this.plugin, 60L);
    14. }
    15. }
     
  10. Offline

    maxben34

    This is because you are casting a block to a collection.
     
  11. Offline

    blablubbabc

    Jordymt
    It's because your are casting the list of blocks to a single block:
    Block explosion = (Block) e.blockList();

    You have to iterator over the list and generate the BlockState of EACH block (not only one block).

    Simple example (from the ticket I linked above):

    Code:
    @EventHandler
    public void explode(EntityExplodeEvent event)
    {
        for(Block b:event.blockList())
        {
            final BlockState bs = b.getState();
            Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable(){
                public void run()
                {
                    bs.update(true);
                }
            });
        }
    }
    This has potential to be improved, for example adding the generated BlockState's to some sort fo collection and only start one delayed task for all blocks, instead one task for each.
     
    Jordymt likes this.
  12. Offline

    Jordymt



    Thank you for your awnser, it worked :D

    I liked everyone in the topic that helped with some code :D
     
Thread Status:
Not open for further replies.

Share This Page