diff --git a/src/com/massivecraft/factions/Conf.java b/src/com/massivecraft/factions/Conf.java index b1c8a6bf..9e1fcc3a 100644 --- a/src/com/massivecraft/factions/Conf.java +++ b/src/com/massivecraft/factions/Conf.java @@ -106,6 +106,7 @@ public class Conf public static boolean handleExploitObsidianGenerators = true; public static boolean handleExploitEnderPearlClipping = true; public static boolean handleExploitInteractionSpam = true; + public static boolean handleExploitTNTWaterlog = false; public static boolean homesEnabled = true; public static boolean homesMustBeInClaimedTerritory = true; diff --git a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java index 83d702ec..4ddb8156 100644 --- a/src/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -1,8 +1,10 @@ package com.massivecraft.factions.listeners; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.List; import java.text.MessageFormat; import java.util.Set; @@ -13,6 +15,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -113,6 +116,29 @@ public class FactionsEntityListener implements Listener return; } } + + // TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but... + // this optional change below provides workaround for waterwalling providing perfect protection, + // and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots + Block center = event.getLocation().getBlock(); + if (event.getEntity() instanceof TNTPrimed && Conf.handleExploitTNTWaterlog && center.isLiquid()) + { + // a single surrounding block in all 6 directions is broken if the material is weak enough + List targets = new ArrayList(); + targets.add(center.getRelative(0, 0, 1)); + targets.add(center.getRelative(0, 0, -1)); + targets.add(center.getRelative(0, 1, 0)); + targets.add(center.getRelative(0, -1, 0)); + targets.add(center.getRelative(1, 0, 0)); + targets.add(center.getRelative(-1, 0, 0)); + for (Block target : targets) + { + int id = target.getTypeId(); + // ignore air, bedrock, water, lava, obsidian, enchanting table... too bad we can't get a working material durability # yet + if (id != 0 && (id < 7 || id > 11) && id != 49 && id != 116) + target.breakNaturally(); + } + } } // mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled