Handle BlockExplodeEvent explicitly.

This commit cleans up the old fake event show that was implemented when
the BlockExplodeEvent was introduced and caused all sorts of issues back
in the day. It should have been cleaned up years ago, but "if it ain't
broke"... Well, it is now! With this commit, however, we get rid of the
constructor invocation that throws up, but we obviously need to replace
it with something else to take care of the problem it used to fix.

The handler is close to a carbon copy of the EntityExplodeEvent handler,
simply because the code isn't very reusable due to direct method calls
on the event object itself. But because of the refactoring step of the
previous commit, we don't actually have to explicitly repeat the gnarly
"repairable" code that handles the block list, yay... We obviously don't
have an entity to check for (and remove from the monster manager), and
we need to dig a little deeper for the Location object needed for the
region check, but other than that, it's the same thing.

Fixes #796
This commit is contained in:
Andreas Troelsen 2024-07-23 02:18:18 +02:00
parent 8122c535df
commit 17317fa0ae
3 changed files with 31 additions and 13 deletions

View File

@ -11,6 +11,8 @@ These changes will (most likely) be included in the next version.
## [Unreleased]
### Fixed
- MobArena no longer throws errors when handling block explosions on Minecraft 1.21.
## [0.108] - 2024-01-01
### Added

View File

@ -48,6 +48,7 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.block.BlockIgniteEvent;
@ -453,6 +454,32 @@ public class ArenaListener
handleExplodeEventBlocks(event.blockList());
}
public void onBlockExplode(BlockExplodeEvent event) {
if (!arena.getRegion().contains(event.getBlock().getLocation(), 10))
return;
// Cancel if the arena isn't running
if (!arena.isRunning()) {
event.setCancelled(true);
return;
}
// Uncancel, just in case.
event.setCancelled(false);
// If the arena isn't destructible, just clear the blocklist.
if (!softRestore && protect) {
List<Block> blocks = new LinkedList<>(arena.getBlocks());
event.blockList().retainAll(blocks);
return;
}
if (!softRestoreDrops)
event.setYield(0);
handleExplodeEventBlocks(event.blockList());
}
private void handleExplodeEventBlocks(List<Block> blocks) {
// Handle all the blocks in the block list.
for (Block b : blocks) {

View File

@ -198,19 +198,8 @@ public class MAGlobalListener implements Listener
@EventHandler(priority = EventPriority.HIGHEST)
public void blockExplode(BlockExplodeEvent event) {
// Create a copy of the block list so we can clear and re-add
List<Block> blocks = new ArrayList<>(event.blockList());
// Account for Spigot's messy extra event
EntityExplodeEvent fake = new EntityExplodeEvent(null, event.getBlock().getLocation(), blocks, event.getYield());
fake.setCancelled(event.isCancelled());
entityExplode(fake);
// Copy the values over
event.setCancelled(fake.isCancelled());
event.blockList().clear();
event.blockList().addAll(fake.blockList());
event.setYield(fake.getYield());
for (Arena arena : am.getArenas())
arena.getEventListener().onBlockExplode(event);
}
@EventHandler(priority = EventPriority.NORMAL)