Explosion - get affected blocks

Is it possible to get the affacted blocks of an explosion and cancel the explosion for blocks?

Yes. However it is currently impossible to work out what item entities spawn for each given block being broken.

I just need the block locations.

ExplosionEvent.Detonate extends ChangeBlockEvent Which has a getTransactions method, which will return the transactions of blocks being changed by the explosion.

From that you can find out what the blocks are being changed from, to, and modify the result.

1 Like

Is it possible to prevent the damage on other enities?

Have a look at AffectsEntityEvent.

Just out of interest does your IDE have any sort of code completion? Normally my first step when answering these sorts of questions I turn to my IDE and create an event listener, then see what code completions come up.

If I can’t find it I have a quick look through the source code of SpongeAPI (doesn’t even need to be the implementations, I understand that code can be confusing to new comers) to see if I can find what I’m looking for.

Sometimes it’s a little harder to find where methods are coming from compared to bukkit due to the event hierarchy, but it’s because of the same event hierarchy why sponge is so flexible so I think the trade offs are worth it.

To modify the result, i can only remove the “Transaction” from “e.getTransactions()” and that blocks will not be affected?

Like this:

        List<Transaction<BlockSnapshot>> toRemove = new ArrayList<Transaction<BlockSnapshot>>();
        for (Transaction<BlockSnapshot> bl:e.getTransactions()) {
        	BlockSnapshot b = bl.getOriginal();
                if (b.getState().getType().getName().contains("TNT") && !region.canFire()){
        		toRemove.add(bl);
    			continue;
        	} 
        if (!toRemove.isEmpty()){
        	e.getTransactions().removeAll(toRemove);
        }

Using “e.getTransactions().removeAll(toRemove);” is all i need to remove this blocks from explosion?
Thanks.

You can just use bl.setCancellced(true);

for (Transaction<BlockSnapshot> bl:e.getTransactions()) {
    BlockSnapshot b = bl.getOriginal();
    if (b.getState().getType().equals(BlockTypes.TNT) &! region.canFire()){
       bl.setValid(false);
    }
}

Can i only remove the blocks from explosion inside a region? This will cancel the explosion at all right?

For each block that should be removed due to the explosion, there’s a Transaction in the event that can be canceled. bl.setValid(false); will only cancel the removal of a particular block. This means that you can check if the Block behind the Transaction is in the region and then cancel the Transaction if it is.

Humm. make sense, but bl (Transaction) does have .setCancelled() method:

Oh I’m sorry. It’s actually .setValid();