diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java index 6624e5111..b45a48402 100644 --- a/src/main/java/com/sk89q/worldedit/LocalWorld.java +++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java @@ -32,6 +32,14 @@ import com.sk89q.worldedit.regions.Region; * @author sk89q */ public abstract class LocalWorld { + /** + * Named flags to use as parameters to {@link LocalWorld#killMobs(Vector, int, int)} + */ + public class KillFlags { + public static final int PETS = 1 << 0; + public static final int NPCS = 1 << 1; + } + /** * Random generator. */ @@ -268,17 +276,35 @@ public abstract class LocalWorld { * @param radius * @return */ - public abstract int killMobs(Vector origin, int radius); + @Deprecated + public int killMobs(Vector origin, int radius) { + return killMobs(origin, radius, false); + } + + /** + * Kill mobs in an area. + * + * @param origin + * @param radius -1 for all mobs + * @param flags various flags that determine what to kill + * @return + */ + @Deprecated + public int killMobs(Vector origin, int radius, boolean killPets) { + return killMobs(origin, radius, killPets ? KillFlags.PETS : 0); + } /** * Kill mobs in an area. * * @param origin * @param radius - * @param killPets + * @param killflags * @return */ - public abstract int killMobs(Vector origin, int radius, boolean killPets); + public int killMobs(Vector origin, double radius, int flags) { + return killMobs(origin, (int) radius, (flags & KillFlags.PETS) != 0); + } /** * Remove entities in an area. diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 40af47b6b..73df0e9ee 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -488,41 +488,43 @@ public class BukkitWorld extends LocalWorld { } - /** - * Kill mobs in an area, excluding tamed wolves. - * - * @param origin - * @param radius -1 for all mobs - * @return - */ - @Override - public int killMobs(Vector origin, int radius) { - return killMobs(origin, radius, false); - } - /** * Kill mobs in an area. * - * @param origin - * @param radius -1 for all mobs - * @param killPets true to kill tames wolves + * @param origin The center of the area to kill mobs in. + * @param radius Maximum distance to kill mobs at; radius < 0 means kill all mobs + * @param flags various flags that determine what to kill * @return */ @Override - public int killMobs(Vector origin, int radius, boolean killPets) { + public int killMobs(Vector origin, double radius, int flags) { + boolean killPets = (flags & KillFlags.PETS) != 0; + boolean killNPCs = (flags & KillFlags.NPCS) != 0; + int num = 0; - double radiusSq = Math.pow(radius, 2); + double radiusSq = radius * radius; + + Location bukkitOrigin = BukkitUtil.toLocation(world, origin); for (LivingEntity ent : world.getLivingEntities()) { + if (ent instanceof HumanEntity) { + continue; + } + if (!killPets && ent instanceof Tameable && ((Tameable) ent).isTamed()) { continue; // tamed wolf } - if (ent instanceof LivingEntity && !(ent instanceof HumanEntity)) { - if (radius == -1 - || origin.distanceSq(BukkitUtil.toVector(ent.getLocation())) <= radiusSq) { - ent.remove(); - ++num; + + try { + // Temporary solution until org.bukkit.entity.NPC is widely deployed. + if (!killNPCs && Class.forName("org.bukkit.entity.NPC").isAssignableFrom(ent.getClass())) { + continue; } + } catch (ClassNotFoundException e) {} + + if (radius < 0 || bukkitOrigin.distanceSquared(ent.getLocation()) <= radiusSq) { + ent.remove(); + ++num; } } diff --git a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java index 692c2c34a..0689b852f 100644 --- a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java @@ -26,6 +26,7 @@ import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; import com.sk89q.worldedit.*; +import com.sk89q.worldedit.LocalWorld.KillFlags; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.patterns.*; import com.sk89q.worldedit.regions.CuboidRegion; @@ -344,11 +345,13 @@ public class UtilityCommands { @Command( aliases = { "butcher" }, usage = "[radius]", - flags = "p", + flags = "pn", desc = "Kill all or nearby mobs", help = "Kills nearby mobs, or all mobs if you don't specify a radius.\n" + - "The -p flag makes /butcher also kill pets.", + "Flags:" + + " -p also kill pets.\n" + + " -n also kill NPCs.", min = 0, max = 1 ) @@ -361,7 +364,12 @@ public class UtilityCommands { int radius = args.argsLength() > 0 ? Math.max(1, args.getInteger(0)) : -1; Vector origin = session.getPlacementPosition(player); - int killed = player.getWorld().killMobs(origin, radius, args.hasFlag('p')); + + int flags = 0; + if (args.hasFlag('p')) flags |= KillFlags.PETS; + if (args.hasFlag('n')) flags |= KillFlags.NPCS; + + int killed = player.getWorld().killMobs(origin, radius, flags); player.print("Killed " + killed + " mobs."); }