Fixes TNT protection: split TNT flag into TNT_DAMAGE (SETTING) and TNT_PRIMING (PROTECTION)

#566 and #649
This commit is contained in:
Florian CUNY 2019-05-12 15:26:51 +02:00
parent 5e9460e624
commit e0b942063b
3 changed files with 58 additions and 17 deletions

View File

@ -13,13 +13,27 @@ import org.bukkit.event.player.PlayerInteractEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
import java.util.Arrays;
import java.util.List;
/**
* Protects islands from visitors blowing things up
* @author tastybento
*
*/
public class TNTListener extends FlagListener {
/**
* Contains {@link EntityType}s that generates an explosion.
* @since 1.5.0
*/
private List<EntityType> tntTypes = Arrays.asList(EntityType.PRIMED_TNT, EntityType.MINECART_TNT);
/**
* Contains {@link Material}s that can be used to prime a TNT.
* @since 1.5.0
*/
private List<Material> primingItems = Arrays.asList(Material.FLINT_AND_STEEL, Material.FIRE_CHARGE);
/**
* Protect TNT from being set light by a fire arrow
* @param e - event
@ -35,7 +49,7 @@ public class TNTListener extends FlagListener {
Projectile projectile = (Projectile) e.getEntity();
// Find out who fired it
if (projectile.getShooter() instanceof Player && projectile.getFireTicks() > 0
&& !checkIsland(e, (Player)projectile.getShooter(), e.getBlock().getLocation(), Flags.BREAK_BLOCKS)) {
&& !checkIsland(e, (Player)projectile.getShooter(), e.getBlock().getLocation(), Flags.TNT_PRIMING)) {
// Remove the arrow
projectile.remove();
e.setCancelled(true);
@ -43,9 +57,8 @@ public class TNTListener extends FlagListener {
}
}
/**
* Protect against priming of TNT unless break blocks is allowed
* Protect against priming of TNT unless TNT priming is allowed
* @param e - event
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
@ -53,20 +66,20 @@ public class TNTListener extends FlagListener {
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)
&& e.getClickedBlock() != null
&& e.getClickedBlock().getType().equals(Material.TNT)
&& e.getMaterial().equals(Material.FLINT_AND_STEEL)) {
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BREAK_BLOCKS);
&& primingItems.contains(e.getMaterial())) {
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.TNT_PRIMING);
}
}
/**
* Prevent TNT damage from explosion
* Prevents TNT explosion from breaking blocks
* @param e - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onExplosion(final EntityExplodeEvent e) {
// Remove any blocks from the explosion list if they are inside a protected area and if the entity was a TNT
if (e.getEntityType().equals(EntityType.PRIMED_TNT)
&& e.blockList().removeIf(b -> getIslands().getProtectedIslandAt(b.getLocation()).map(i -> !i.isAllowed(Flags.TNT)).orElse(false))) {
if (tntTypes.contains(e.getEntityType())
&& e.blockList().removeIf(b -> getIslands().getProtectedIslandAt(b.getLocation()).map(i -> !i.isAllowed(Flags.TNT_DAMAGE)).orElse(false))) {
// If any were removed, then prevent damage too
e.setCancelled(true);
}

View File

@ -1,12 +1,7 @@
package world.bentobox.bentobox.lists;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
@ -57,6 +52,10 @@ import world.bentobox.bentobox.listeners.flags.worldsettings.RemoveMobsListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.TreesGrowingOutsideRangeListener;
import world.bentobox.bentobox.managers.RanksManager;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Contains built-in {@link Flag Flags} that are registered by default into the {@link world.bentobox.bentobox.managers.FlagsManager FlagsManager} at startup.
*/
@ -189,6 +188,15 @@ public final class Flags {
* @see FireListener
*/
public static final Flag FLINT_AND_STEEL = new Flag.Builder("FLINT_AND_STEEL", Material.FLINT_AND_STEEL).listener(new FireListener()).build();
/**
* Prevents players from priming TNT.
* @since 1.5.0
*
* @see TNTListener
*/
public static final Flag TNT_PRIMING = new Flag.Builder("TNT_PRIMING", Material.TNT).listener(new TNTListener()).build();
/**
* Prevents players from extinguishing fires.
* @see FireListener
@ -229,6 +237,10 @@ public final class Flags {
public static final Flag EXPERIENCE_PICKUP = new Flag.Builder("EXPERIENCE_PICKUP", Material.EXPERIENCE_BOTTLE).listener(new ExperiencePickupListener()).build();
// TNT
/**
* @deprecated As of 1.5.0, for removal.
*/
@Deprecated
public static final Flag TNT = new Flag.Builder("TNT", Material.TNT).listener(new TNTListener()).build();
// Island lock
@ -279,10 +291,16 @@ public final class Flags {
*/
public static final Flag LEAF_DECAY = new Flag.Builder("LEAF_DECAY", Material.OAK_LEAVES).type(Type.SETTING).listener(new DecayListener()).defaultSetting(true).build();
/**
* If {@code false}, prevents TNT from breaking blocks and damaging nearby entities.
* @since 1.5.0
* @see TNTListener
*/
public static final Flag TNT_DAMAGE = new Flag.Builder("TNT_DAMAGE", Material.TNT).type(Type.SETTING).build();
/*
* World Settings - they apply to every island in the game worlds.
*/
public static final Flag ENDER_CHEST = new Flag.Builder("ENDER_CHEST", Material.ENDER_CHEST)
.type(Type.WORLD_SETTING)
.listener(new EnderChestListener())

View File

@ -906,9 +906,19 @@ protection:
description: "Toggle use"
name: "Spawn eggs"
hint: "No throwing spawn eggs"
TNT:
description: "Toggle TNT damage"
TNT_DAMAGE:
description: |-
&aAllow TNT and TNT minecarts
&ato break blocks and damage
&aentities.
name: "TNT damage"
TNT_PRIMING:
description: |-
&aPrevents priming TNT.
&aIt does not override the
&aFlint and steel protection.
name: "TNT priming"
hint: "No TNT priming"
TRADING:
description: "Toggle trading"
name: "Villager trading"