From 5316130ae8b7dc905667dcf07472d71df1edc116 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sun, 4 Nov 2012 14:46:36 -0800 Subject: [PATCH] Better handle potion blocking with dispensers/splash potions. --- .../worldguard/bukkit/WorldConfiguration.java | 2 ++ .../bukkit/WorldGuardBlockListener.java | 27 ++++++++++++++++ .../bukkit/WorldGuardEntityListener.java | 31 +++++++++++++++++-- .../bukkit/WorldGuardPlayerListener.java | 28 ++++++++++++++--- 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldConfiguration.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldConfiguration.java index 6c74a068..de3b4ad4 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldConfiguration.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldConfiguration.java @@ -76,6 +76,7 @@ public class WorldConfiguration { public int spongeRadius; public boolean disableExpDrops; public Set blockPotions; + public boolean blockPotionsAlways; public boolean pumpkinScuba; public boolean redstoneSponges; public boolean noPhysicsGravel; @@ -300,6 +301,7 @@ private void loadConfiguration() { blockPotions.add(effect); } } + blockPotionsAlways = getBoolean("gameplay.block-potions-overly-reliably", false); simulateSponge = getBoolean("simulation.sponge.enable", true); spongeRadius = Math.max(1, getInt("simulation.sponge.radius", 3)) - 1; diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java index 8068359f..85b25b8d 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java @@ -22,6 +22,7 @@ import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -31,6 +32,7 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFromToEvent; @@ -45,6 +47,9 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.Potion; +import org.bukkit.potion.PotionEffect; + import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockType; import com.sk89q.worldedit.blocks.ItemType; @@ -816,4 +821,26 @@ public void onBlockPistonRetract(BlockPistonRetractEvent event) { } } } + + /* + * Called when a block is damaged. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onBlockDispense(BlockDispenseEvent event) { + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + + if (wcfg.blockPotions.size() > 0) { + ItemStack item = event.getItem(); + if (item.getType() == Material.POTION) { + Potion potion = Potion.fromItemStack(item); + for (PotionEffect effect : potion.getEffects()) { + if (potion.isSplash() && wcfg.blockPotions.contains(effect.getType())) { + event.setCancelled(true); + return; + } + } + } + } + } } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java index 7c8cedc3..94f417f0 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java @@ -40,6 +40,7 @@ import org.bukkit.entity.Projectile; import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Tameable; +import org.bukkit.entity.ThrownPotion; import org.bukkit.entity.Wolf; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -62,6 +63,7 @@ import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockID; @@ -811,14 +813,39 @@ public void onFoodLevelChange(FoodLevelChangeEvent event) { @EventHandler(ignoreCancelled = true) public void onPotionSplash(PotionSplashEvent event) { - GlobalRegionManager global = plugin.getGlobalRegionManager(); + Entity entity = event.getEntity(); + ThrownPotion potion = event.getPotion(); + + ConfigurationManager cfg = plugin.getGlobalStateManager(); + WorldConfiguration wcfg = cfg.get(entity.getWorld()); + + if (wcfg.blockPotionsAlways && wcfg.blockPotions.size() > 0) { + boolean blocked = false; + + for (PotionEffect effect : potion.getEffects()) { + if (wcfg.blockPotions.contains(effect.getType())) { + blocked = true; + break; + } + } + + if (blocked) { + event.setCancelled(true); + return; + } + } + + GlobalRegionManager regionMan = plugin.getGlobalRegionManager(); + int blockedEntities = 0; for (LivingEntity e : event.getAffectedEntities()) { - if (!global.allows(DefaultFlag.POTION_SPLASH, e.getLocation(), e instanceof Player ? plugin.wrapPlayer((Player) e) : null)) { + if (!regionMan.allows(DefaultFlag.POTION_SPLASH, e.getLocation(), + e instanceof Player ? plugin.wrapPlayer((Player) e) : null)) { event.setIntensity(e, 0); ++blockedEntities; } } + if (blockedEntities == event.getAffectedEntities().size()) { event.setCancelled(true); } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java index 3d1ce1c5..1c27f4bc 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlayerListener.java @@ -423,19 +423,37 @@ public void onPlayerInteract(PlayerInteractEvent event) { } } - if (wcfg.blockPotions.size() > 0 - && !plugin.hasPermission(player, "worldguard.override.potions")) { + if (wcfg.blockPotions.size() > 0) { ItemStack item = event.getItem(); if (item.getType() == Material.POTION) { + PotionEffect blockedEffect = null; + Potion potion = Potion.fromItemStack(item); for (PotionEffect effect : potion.getEffects()) { if (wcfg.blockPotions.contains(effect.getType())) { - player.sendMessage(ChatColor.RED + "Sorry, potions with " - + effect.getType().getName() + " are presently disabled."); - event.setUseItemInHand(Result.DENY); + blockedEffect = effect; break; } } + + if (blockedEffect != null) { + if (plugin.hasPermission(player, "worldguard.override.potions")) { + if (potion.isSplash() && wcfg.blockPotionsAlways) { + player.sendMessage(ChatColor.RED + "Sorry, potions with " + + blockedEffect.getType().getName() + + " can't be thrown, even if you have a permission to " + + "bypass it, due to limitations (and because overly-reliable potion blocking is on)."); + event.setUseItemInHand(Result.DENY); + return; + } + } else { + player.sendMessage(ChatColor.RED + "Sorry, potions with " + + blockedEffect.getType().getName() + " are presently disabled."); + event.setUseItemInHand(Result.DENY); + return; + } + + } } } }