Fix TNT explosions between territories

This commit is contained in:
utarwyn 2018-05-11 18:09:11 +02:00
parent f30cd44b54
commit 055ab7dd90
1 changed files with 65 additions and 36 deletions

View File

@ -207,44 +207,36 @@ public class FactionsEntityListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onEntityExplode(EntityExplodeEvent event) { public void onEntityExplode(EntityExplodeEvent event) {
Location loc = event.getLocation(); // Before we need to check the location where the block is placed
Entity boomer = event.getEntity(); if (!this.checkExplosionForBlock(event, event.getLocation().getBlock())) {
Faction faction = Board.getInstance().getFactionAt(new FLocation(loc));
if (faction.noExplosionsInTerritory() || (faction.isPeaceful() && Conf.peacefulTerritoryDisableBoom)) {
// faction is peaceful and has explosions set to disabled
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
boolean online = faction.hasPlayersOnline(); Entity boomer = event.getEntity();
Iterator<Block> blockList = event.blockList().iterator();
//TODO: :( // Loop the blocklist to run checks on each aimed block
if (boomer instanceof Creeper && ((faction.isWilderness() && Conf.wildernessBlockCreepers && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) || while (blockList.hasNext()) {
(faction.isNormal() && (online ? Conf.territoryBlockCreepers : Conf.territoryBlockCreepersWhenOffline)) || Block block = blockList.next();
(faction.isWarZone() && Conf.warZoneBlockCreepers) ||
faction.isSafeZone())) { if (!this.checkExplosionForBlock(event, block)) {
// creeper which needs prevention // The block don't have to explode
event.setCancelled(true); blockList.remove();
} else if ( }
// it's a bit crude just using fireball protection for Wither boss too, but I'd rather not add in a whole new set of xxxBlockWitherExplosion or whatever }
(boomer instanceof Fireball || boomer instanceof WitherSkull || boomer instanceof Wither) && ((faction.isWilderness() && Conf.wildernessBlockFireballs && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) ||
(faction.isNormal() && (online ? Conf.territoryBlockFireballs : Conf.territoryBlockFireballsWhenOffline)) || // Cancel the event if no block will explode
(faction.isWarZone() && Conf.warZoneBlockFireballs) || if (event.blockList().isEmpty()) {
faction.isSafeZone())) {
// ghast fireball which needs prevention
event.setCancelled(true);
} else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && ((faction.isWilderness() && Conf.wildernessBlockTNT && !Conf.worldsNoWildernessProtection.contains(loc.getWorld().getName())) ||
(faction.isNormal() && (online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline)) ||
(faction.isWarZone() && Conf.warZoneBlockTNT) ||
(faction.isSafeZone() && Conf.safeZoneBlockTNT))) {
// TNT which needs prevention
event.setCancelled(true); event.setCancelled(true);
// Or handle the exploit of TNT in water/lava
} else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && Conf.handleExploitTNTWaterlog) { } else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && Conf.handleExploitTNTWaterlog) {
// TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but... // TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but...
// this change below provides workaround for waterwalling providing perfect protection, // this change below provides workaround for waterwalling providing perfect protection,
// and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots // and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots
Block center = loc.getBlock(); Block center = event.getLocation().getBlock();
if (center.isLiquid()) { if (center.isLiquid()) {
// a single surrounding block in all 6 directions is broken if the material is weak enough // a single surrounding block in all 6 directions is broken if the material is weak enough
List<Block> targets = new ArrayList<>(); List<Block> targets = new ArrayList<>();
@ -265,6 +257,43 @@ public class FactionsEntityListener implements Listener {
} }
} }
private boolean checkExplosionForBlock(EntityExplodeEvent event, Block block) {
Entity boomer = event.getEntity();
Faction faction = Board.getInstance().getFactionAt(new FLocation(block.getLocation()));
if (faction.noExplosionsInTerritory() || (faction.isPeaceful() && Conf.peacefulTerritoryDisableBoom)) {
// faction is peaceful and has explosions set to disabled
return false;
}
boolean online = faction.hasPlayersOnline();
if (boomer instanceof Creeper && ((faction.isWilderness() && Conf.wildernessBlockCreepers && !Conf.worldsNoWildernessProtection.contains(block.getWorld().getName())) ||
(faction.isNormal() && (online ? Conf.territoryBlockCreepers : Conf.territoryBlockCreepersWhenOffline)) ||
(faction.isWarZone() && Conf.warZoneBlockCreepers) ||
faction.isSafeZone())) {
// creeper which needs prevention
return false;
} else if (
// it's a bit crude just using fireball protection for Wither boss too, but I'd rather not add in a whole new set of xxxBlockWitherExplosion or whatever
(boomer instanceof Fireball || boomer instanceof WitherSkull || boomer instanceof Wither) && ((faction.isWilderness() && Conf.wildernessBlockFireballs && !Conf.worldsNoWildernessProtection.contains(block.getWorld().getName())) ||
(faction.isNormal() && (online ? Conf.territoryBlockFireballs : Conf.territoryBlockFireballsWhenOffline)) ||
(faction.isWarZone() && Conf.warZoneBlockFireballs) ||
faction.isSafeZone())) {
// ghast fireball which needs prevention
return false;
} else if ((boomer instanceof TNTPrimed || boomer instanceof ExplosiveMinecart) && ((faction.isWilderness() && Conf.wildernessBlockTNT && !Conf.worldsNoWildernessProtection.contains(block.getWorld().getName())) ||
(faction.isNormal() && (online ? Conf.territoryBlockTNT : Conf.territoryBlockTNTWhenOffline)) ||
(faction.isWarZone() && Conf.warZoneBlockTNT) ||
(faction.isSafeZone() && Conf.safeZoneBlockTNT))) {
// TNT which needs prevention
return false;
}
// No condition retained, destroy the block!
return true;
}
//For disabling enderpearl throws //For disabling enderpearl throws
@EventHandler @EventHandler
public void onPearl(PlayerInteractEvent e) { public void onPearl(PlayerInteractEvent e) {