Fixed chorus flowers not being protected from breaking if destroyed by arrow/trident

Fixes https://github.com/BentoBoxWorld/BentoBox/issues/812
Note it can cause the block to flicker or to turn into a ghost block. The Bukkit API does not provide a way to actually cancel the block breaking, therefore we need to resort to a delayed task.
This commit is contained in:
Florian CUNY 2019-12-29 14:48:02 +01:00
parent 382bb2c574
commit 1a8be26010

View File

@ -3,6 +3,8 @@ package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.ItemFrame;
@ -13,6 +15,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
@ -130,4 +133,33 @@ public class BreakBlocksListener extends FlagListener {
}
return false;
}
/**
* Prevents Chorus Flowers from being broken by an arrow or a trident
* @param e event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onProjectileHitBreakBlock(ProjectileHitEvent e) {
// We want to make sure this is an actual projectile (arrow or trident)
if (!(e.getEntity() instanceof AbstractArrow)) {
return;
}
// We want to make sure it hit a CHORUS_FLOWER
if (e.getHitBlock() == null || !e.getHitBlock().getType().equals(Material.CHORUS_FLOWER)) {
return;
}
// Find out who fired the arrow
if (e.getEntity().getShooter() instanceof Player) {
if (!checkIsland(e, (Player) e.getEntity().getShooter(), e.getHitBlock().getLocation(), Flags.BREAK_BLOCKS)) {
final BlockData data = e.getHitBlock().getBlockData();
// We seemingly can't prevent the block from being destroyed
// So we need to put it back with a slight delay (yup, this is hacky - it makes the block flicker sometimes)
e.getHitBlock().setType(Material.AIR); // prevents the block from dropping a chorus flower
getPlugin().getServer().getScheduler().runTask(getPlugin(), () -> e.getHitBlock().setBlockData(data, true));
// Sorry, this might also cause some ghost blocks!
}
}
}
}