diff --git a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java index 6dd9d2d0..b6d73b9f 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardBlockListener.java @@ -39,7 +39,6 @@ import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; @@ -272,55 +271,80 @@ public void onBlockFromTo(BlockFromToEvent event) { } } + /** + * Determines whether fire can spread into a block. + * + * @param block The block in question + * @return true if allowed, false otherwise + */ + private boolean isFireSpreadAllowed(Block block) { + final ConfigurationManager cfg = plugin.getGlobalStateManager(); + final WorldConfiguration wcfg = cfg.get(block.getWorld()); + + if (wcfg.disableFireSpread) { + return false; + } + + if (wcfg.fireSpreadDisableToggle) { + return false; + } + + if (!wcfg.highFreqFlags) { + return true; + } + + if (!wcfg.useRegions) { + return true; + } + + final Vector pt = toVector(block); + final RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld()); + final ApplicableRegionSet set = mgr.getApplicableRegions(pt); + + return set.allows(DefaultFlag.FIRE_SPREAD); + + } + /* * Called when a block gets ignited. */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockIgnite(BlockIgniteEvent event) { - IgniteCause cause = event.getCause(); - Block block = event.getBlock(); - World world = block.getWorld(); + final Block block = event.getBlock(); + final World world = block.getWorld(); - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(world); + final ConfigurationManager cfg = plugin.getGlobalStateManager(); + final WorldConfiguration wcfg = cfg.get(world); if (cfg.activityHaltToggle) { event.setCancelled(true); return; } - boolean isFireSpread = cause == IgniteCause.SPREAD; - if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) { - event.setCancelled(true); - return; + final ApplicableRegionSet set; + + if (wcfg.useRegions) { + Vector pt = toVector(block); + RegionManager mgr = plugin.getGlobalRegionManager().get(world); + set = mgr.getApplicableRegions(pt); + } else { + set = null; } - if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) { - event.setCancelled(true); - return; - } + switch (event.getCause()) { + case SPREAD: + if (!isFireSpreadAllowed(block)) { + event.setCancelled(true); + return; + } - if (wcfg.disableFireSpread && isFireSpread) { - event.setCancelled(true); - return; - } + if (wcfg.disableFireSpreadBlocks.size() <= 0) { + break; + } - if (wcfg.blockLighter && (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) - && event.getPlayer() != null - && !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) { - event.setCancelled(true); - return; - } - - if (wcfg.fireSpreadDisableToggle && isFireSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.disableFireSpreadBlocks.size() > 0 && isFireSpread) { - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); + final int x = block.getX(); + final int y = block.getY(); + final int z = block.getZ(); if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z)) || wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z)) @@ -330,53 +354,92 @@ public void onBlockIgnite(BlockIgniteEvent event) { event.setCancelled(true); return; } - } - if (wcfg.useRegions) { - Vector pt = toVector(block); - Player player = event.getPlayer(); - RegionManager mgr = plugin.getGlobalRegionManager().get(world); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); + break; - if (player != null && !plugin.getGlobalRegionManager().hasBypass(player, world)) { - LocalPlayer localPlayer = plugin.wrapPlayer(player); - - // this is preliminarily handled in the player listener under handleBlockRightClick - // why it's handled here too, no one knows - if (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) { - if (!set.allows(DefaultFlag.LIGHTER) - && !set.canBuild(localPlayer) - && !plugin.hasPermission(player, "worldguard.override.lighter")) { - event.setCancelled(true); - return; - } - } - } - - if (wcfg.highFreqFlags && isFireSpread - && !set.allows(DefaultFlag.FIRE_SPREAD)) { + case LIGHTNING: + if (wcfg.preventLightningFire) { event.setCancelled(true); return; } - if (wcfg.highFreqFlags && cause == IgniteCause.LAVA - && !set.allows(DefaultFlag.LAVA_FIRE)) { + if (!wcfg.useRegions) { + break; + } + + if (set.allows(DefaultFlag.LIGHTNING)) { + break; + } + + event.setCancelled(true); + return; + + case LAVA: + if (wcfg.preventLavaFire) { event.setCancelled(true); return; } - if (cause == IgniteCause.FIREBALL && event.getPlayer() == null) { - // wtf bukkit, FIREBALL is supposed to be reserved to players - if (!set.allows(DefaultFlag.GHAST_FIREBALL)) { - event.setCancelled(true); - return; - } + if (!wcfg.useRegions) { + break; } - if (cause == IgniteCause.LIGHTNING && !set.allows(DefaultFlag.LIGHTNING)) { + if (!wcfg.highFreqFlags) { + break; + } + + if (set.allows(DefaultFlag.LAVA_FIRE)) { + break; + } + + event.setCancelled(true); + return; + + case FIREBALL: + if (wcfg.useRegions && event.getPlayer() == null && !set.allows(DefaultFlag.GHAST_FIREBALL)) { event.setCancelled(true); return; } + + /* FALL-THROUGH */ + + case FLINT_AND_STEEL: + final Player player = event.getPlayer(); + if (player == null) { + break; + } + + if (wcfg.blockLighter && !plugin.hasPermission(player, "worldguard.override.lighter")) { + event.setCancelled(true); + return; + } + + if (!wcfg.useRegions) { + break; + } + + if (plugin.getGlobalRegionManager().hasBypass(player, world)) { + break; + } + + final LocalPlayer localPlayer = plugin.wrapPlayer(player); + + // Lighters are preliminarily handled in the player listener under handleBlockRightClick. + // Why they're handled here too, no one knows + if (set.allows(DefaultFlag.LIGHTER)) { + break; + } + + if (set.canBuild(localPlayer)) { + break; + } + + if (plugin.hasPermission(player, "worldguard.override.lighter")) { + break; + } + + event.setCancelled(true); + return; } } @@ -385,32 +448,19 @@ public void onBlockIgnite(BlockIgniteEvent event) { */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBlockBurn(BlockBurnEvent event) { - ConfigurationManager cfg = plugin.getGlobalStateManager(); - WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); + final ConfigurationManager cfg = plugin.getGlobalStateManager(); + final WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld()); if (cfg.activityHaltToggle) { event.setCancelled(true); return; } - if (wcfg.disableFireSpread) { - event.setCancelled(true); - return; - } - - if (wcfg.fireSpreadDisableToggle) { - Block block = event.getBlock(); - event.setCancelled(true); - checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); - return; - } - if (wcfg.disableFireSpreadBlocks.size() > 0) { - Block block = event.getBlock(); + final Block block = event.getBlock(); if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) { event.setCancelled(true); - checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE); return; } } @@ -420,36 +470,9 @@ public void onBlockBurn(BlockBurnEvent event) { return; } - if (wcfg.useRegions) { - Block block = event.getBlock(); - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); - Vector pt = toVector(block); - RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld()); - ApplicableRegionSet set = mgr.getApplicableRegions(pt); - - if (!set.allows(DefaultFlag.FIRE_SPREAD)) { - checkAndDestroyAround(block.getWorld(), x, y, z, BlockID.FIRE); - event.setCancelled(true); - return; - } - - } - } - - private void checkAndDestroyAround(World world, int x, int y, int z, int required) { - checkAndDestroy(world, x, y, z + 1, required); - checkAndDestroy(world, x, y, z - 1, required); - checkAndDestroy(world, x, y + 1, z, required); - checkAndDestroy(world, x, y - 1, z, required); - checkAndDestroy(world, x + 1, y, z, required); - checkAndDestroy(world, x - 1, y, z, required); - } - - private void checkAndDestroy(World world, int x, int y, int z, int required) { - if (world.getBlockTypeIdAt(x, y, z) == required) { - world.getBlockAt(x, y, z).setTypeId(BlockID.AIR); + if (!isFireSpreadAllowed(event.getBlock())) { + event.setCancelled(true); + return; } } @@ -832,6 +855,18 @@ public void onBlockFade(BlockFadeEvent event) { } break; + case BlockID.FIRE: + if (event.getNewState().getTypeId() != BlockID.AIR) { + return; + } + + if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows( + DefaultFlag.FIRE_EXTINGUISH, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + break; + case BlockID.SOIL: if (wcfg.disableSoilDehydration) { event.setCancelled(true); diff --git a/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java index 575f8253..ca742b9d 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/commands/RegionCommands.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.command.CommandSender; @@ -698,6 +699,8 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept existing = findExistingRegion(regionManager, args.getString(0), true); } + Bukkit.getLogger().info(String.valueOf(existing.volume())); + // Check permissions if (!permModel.mayLookup(existing)) { throw new CommandPermissionsException(); diff --git a/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java b/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java index d83166e1..7e94e1d9 100644 --- a/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java +++ b/src/main/java/com/sk89q/worldguard/protection/flags/DefaultFlag.java @@ -42,6 +42,7 @@ public final class DefaultFlag { public static final StateFlag TNT = new StateFlag("tnt", true, RegionGroup.ALL); public static final StateFlag LIGHTER = new StateFlag("lighter", true); public static final StateFlag FIRE_SPREAD = new StateFlag("fire-spread", true); + public static final StateFlag FIRE_EXTINGUISH = new StateFlag("fire-extinguish", true); public static final StateFlag LAVA_FIRE = new StateFlag("lava-fire", true); public static final StateFlag LIGHTNING = new StateFlag("lightning", true); public static final StateFlag CHEST_ACCESS = new StateFlag("chest-access", false); @@ -109,7 +110,7 @@ public final class DefaultFlag { FEED_DELAY, FEED_AMOUNT, MIN_FOOD, MAX_FOOD, SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT, SOIL_DRY, GAME_MODE, MUSHROOMS, LEAF_DECAY, GRASS_SPREAD, MYCELIUM_SPREAD, VINE_GROWTH, - SEND_CHAT, RECEIVE_CHAT, FIRE_SPREAD, LAVA_FIRE, LAVA_FLOW, WATER_FLOW, + SEND_CHAT, RECEIVE_CHAT, FIRE_SPREAD, FIRE_EXTINGUISH, LAVA_FIRE, LAVA_FLOW, WATER_FLOW, TELE_LOC, SPAWN_LOC, POTION_SPLASH, BLOCKED_CMDS, ALLOWED_CMDS, PRICE, BUYABLE, ENABLE_SHOP }; diff --git a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java index f194e183..40218351 100644 --- a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java +++ b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedCuboidRegion.java @@ -129,30 +129,14 @@ public boolean intersectsWith(ProtectedRegion region) throws UnsupportedIntersec */ @Override - public List getIntersectingRegions(List regions) throws UnsupportedIntersectionException { - List intersectingRegions = new ArrayList(); - - for (ProtectedRegion region : regions) { - if (!intersectsBoundingBox(region)) continue; - - // If both regions are Cuboids and their bounding boxes intersect, they intersect - if (region instanceof ProtectedCuboidRegion) { - intersectingRegions.add(region); - continue; - } else if (region instanceof ProtectedPolygonalRegion) { - // If either region contains the points of the other, - // or if any edges intersect, the regions intersect - if (containsAny(region.getPoints()) - || region.containsAny(getPoints()) - || intersectsEdges(region)) { - intersectingRegions.add(region); - continue; - } - } else { - throw new UnsupportedOperationException("Not supported yet."); - } + public boolean intersectsRegion(ProtectedRegion region) { + if (region instanceof ProtectedPolygonalRegion) { + return intersectsRegionHelper(region); + } else if (region instanceof ProtectedCuboidRegion) { + return intersectsBoundingBox(region); + } else { + throw new UnsupportedOperationException("Not supported yet."); } - return intersectingRegions; } @Override diff --git a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java index e4a551ef..cff11ede 100644 --- a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java +++ b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java @@ -23,7 +23,6 @@ import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.Vector; -import com.sk89q.worldguard.protection.UnsupportedIntersectionException; public class ProtectedPolygonalRegion extends ProtectedRegion { @@ -122,30 +121,6 @@ public boolean contains(Vector pt) { return inside; } - @Override - public List getIntersectingRegions(List regions) throws UnsupportedIntersectionException { - List intersectingRegions = new ArrayList(); - - for (ProtectedRegion region : regions) { - if (!intersectsBoundingBox(region)) continue; - - if (region instanceof ProtectedPolygonalRegion || region instanceof ProtectedCuboidRegion) { - // If either region contains the points of the other, - // or if any edges intersect, the regions intersect - if (containsAny(region.getPoints()) - || region.containsAny(getPoints()) - || intersectsEdges(region)) { - intersectingRegions.add(region); - continue; - } - } else { - throw new UnsupportedOperationException("Not supported yet."); - } - } - return intersectingRegions; - } - - /** * Return the type of region as a user-friendly name. * @@ -158,41 +133,30 @@ public String getTypeName() { @Override public int volume() { - int volume = 0; - // TODO: Fix this - /*int numPoints = points.size(); + int yLength = max.getBlockY() - min.getBlockY() + 1; + + int numPoints = points.size(); if (numPoints < 3) { - return 0; + int xLength = max.getBlockX() - min.getBlockX() + 1; + int zLength = max.getBlockZ() - min.getBlockZ() + 1; + + return xLength * yLength * zLength; } - double area = 0; - int xa, z1, z2; + int area = 0; + BlockVector2D p1, p2; + int s = numPoints - 1; for (int i = 0; i < numPoints; i++) { - xa = points.get(i).getBlockX(); - //za = points.get(i).getBlockZ(); - if (points.get(i + 1) == null) { - z1 = points.get(0).getBlockZ(); - } else { - z1 = points.get(i + 1).getBlockZ(); - } - if (points.get(i - 1) == null) { - z2 = points.get(numPoints - 1).getBlockZ(); - } else { - z2 = points.get(i - 1).getBlockZ(); - } + // Update/define p1 & p2 + p1 = points.get(i); + p2 = points.get(s); - area = area + (xa * (z1 - z2)); + // Do the math, then reassign s + area += ((p2.getBlockX() + .5) + (p1.getBlockX() + .5)) * ((p2.getBlockZ() + .5) - (p1.getBlockZ() + .5)); + s = i; } - - xa = points.get(0).getBlockX(); - //za = points.get(0).getBlockZ(); - - area = area + (xa * (points.get(1).getBlockZ() - points.get(numPoints - 1).getBlockZ())); - - volume = (Math.abs(maxY - minY) + 1) * (int) Math.ceil((Math.abs(area) / 2));*/ - - return volume; + return (int) Math.abs(Math.ceil(area / 2D) * yLength); } } diff --git a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java index 222382b9..29181947 100644 --- a/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java +++ b/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java @@ -28,6 +28,7 @@ import com.sk89q.worldguard.protection.flags.Flag; import java.awt.geom.Line2D; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -487,6 +488,24 @@ public int compareTo(ProtectedRegion other) { return id.compareTo(other.id); } + protected boolean intersectsRegionHelper(ProtectedRegion region) { + if (!intersectsBoundingBox(region)) { + return false; + } + + // If either region contains the points of the other, + // or if any edges intersect, the regions intersect + return containsAny(region.getPoints()) || region.containsAny(getPoints()) || intersectsEdges(region); + } + + public boolean intersectsRegion(ProtectedRegion region) { + if (!(region instanceof ProtectedPolygonalRegion) && (!(region instanceof ProtectedCuboidRegion))) { + throw new UnsupportedOperationException("Not supported yet."); + } + + return intersectsRegionHelper(region); + } + /** * Return the type of region as a user-friendly, lowercase name. * @@ -501,9 +520,16 @@ public int compareTo(ProtectedRegion other) { * @return The elements of {@code regions} that intersect with this region * @throws UnsupportedIntersectionException if an invalid intersection is detected */ - public abstract List getIntersectingRegions( - List regions) - throws UnsupportedIntersectionException; + public List getIntersectingRegions(List regions) throws UnsupportedIntersectionException { + List intersectingRegions = new ArrayList(); + + for (ProtectedRegion region : regions) { + if (intersectsRegion(region)) { + intersectingRegions.add(region); + } + } + return intersectingRegions; + } /** * Checks if the bounding box of a region intersects with with the bounding