diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 7da5ce81..0dc68c45 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -22,6 +22,7 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.command.BrushCommands; import com.sk89q.worldedit.command.ClipboardCommands; import com.sk89q.worldedit.command.SchematicCommands; import com.sk89q.worldedit.command.ScriptingCommands; @@ -223,6 +224,7 @@ public class Fawe { private void setupInjector() { EditSession.inject(); Operations.inject(); + BrushCommands.inject(); ClipboardCommands.inject(); SchematicCommands.inject(); ScriptingCommands.inject(); diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index 6909809b..ad390906 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -52,7 +52,7 @@ public class Settings { limit.MAX_ITERATIONS = 0; for (Entry entry : limits.entrySet()) { String key = entry.getKey(); - if (key.equals("default") || player.hasPermission("fawe.limit." + key)) { + if (key.equals("default") || (player != null && player.hasPermission("fawe.limit." + key))) { FaweLimit newLimit = entry.getValue(); limit.MAX_CHANGES = Math.max(limit.MAX_CHANGES, newLimit.MAX_CHANGES != -1 ? newLimit.MAX_CHANGES : Integer.MAX_VALUE); limit.MAX_BLOCKSTATES = Math.max(limit.MAX_BLOCKSTATES, newLimit.MAX_BLOCKSTATES != -1 ? newLimit.MAX_BLOCKSTATES : Integer.MAX_VALUE); diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java new file mode 100644 index 00000000..c46fedce --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -0,0 +1,284 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command; + +import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.FaweLimit; +import com.boydti.fawe.object.FawePlayer; +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BlockID; +import com.sk89q.worldedit.command.tool.BrushTool; +import com.sk89q.worldedit.command.tool.brush.ButcherBrush; +import com.sk89q.worldedit.command.tool.brush.ClipboardBrush; +import com.sk89q.worldedit.command.tool.brush.CylinderBrush; +import com.sk89q.worldedit.command.tool.brush.GravityBrush; +import com.sk89q.worldedit.command.tool.brush.HollowCylinderBrush; +import com.sk89q.worldedit.command.tool.brush.HollowSphereBrush; +import com.sk89q.worldedit.command.tool.brush.SmoothBrush; +import com.sk89q.worldedit.command.tool.brush.SphereBrush; +import com.sk89q.worldedit.command.util.CreatureButcher; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.pattern.BlockPattern; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.util.command.binding.Switch; +import com.sk89q.worldedit.util.command.parametric.Optional; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Commands to set brush shape. + */ +public class BrushCommands { + + private final WorldEdit worldEdit; + + /** + * Create a new instance. + * + * @param worldEdit reference to WorldEdit + */ + public BrushCommands(WorldEdit worldEdit) { + checkNotNull(worldEdit); + this.worldEdit = worldEdit; + } + + @Command( + aliases = { "sphere", "s" }, + usage = " [radius]", + flags = "h", + desc = "Choose the sphere brush", + help = + "Chooses the sphere brush.\n" + + "The -h flag creates hollow spheres instead.", + min = 1, + max = 2 + ) + @CommandPermissions("worldedit.brush.sphere") + public void sphereBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, + @Optional("2") double radius, @Switch('h') boolean hollow) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setFill(fill); + tool.setSize(radius); + + if (hollow) { + tool.setBrush(new HollowSphereBrush(), "worldedit.brush.sphere"); + } else { + tool.setBrush(new SphereBrush(), "worldedit.brush.sphere"); + } + + player.print(String.format("Sphere brush shape equipped (%.0f).", radius)); + } + + @Command( + aliases = { "cylinder", "cyl", "c" }, + usage = " [radius] [height]", + flags = "h", + desc = "Choose the cylinder brush", + help = + "Chooses the cylinder brush.\n" + + "The -h flag creates hollow cylinders instead.", + min = 1, + max = 3 + ) + @CommandPermissions("worldedit.brush.cylinder") + public void cylinderBrush(Player player, LocalSession session, EditSession editSession, Pattern fill, + @Optional("2") double radius, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius(height); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setFill(fill); + tool.setSize(radius); + + if (hollow) { + tool.setBrush(new HollowCylinderBrush(height), "worldedit.brush.cylinder"); + } else { + tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder"); + } + + player.print(String.format("Cylinder brush shape equipped (%.0f by %d).", radius, height)); + } + + @Command( + aliases = { "clipboard", "copy" }, + usage = "", + desc = "Choose the clipboard brush", + help = + "Chooses the clipboard brush.\n" + + "The -a flag makes it not paste air.\n" + + "Without the -p flag, the paste will appear centered at the target location. " + + "With the flag, then the paste will appear relative to where you had " + + "stood relative to the copied area when you copied it." + ) + @CommandPermissions("worldedit.brush.clipboard") + public void clipboardBrush(Player player, LocalSession session, EditSession editSession, @Switch('a') boolean ignoreAir, @Switch('p') boolean usingOrigin) throws WorldEditException { + ClipboardHolder holder = session.getClipboard(); + Clipboard clipboard = holder.getClipboard(); + + Vector size = clipboard.getDimensions(); + + worldEdit.checkMaxBrushRadius(size.getBlockX()); + worldEdit.checkMaxBrushRadius(size.getBlockY()); + worldEdit.checkMaxBrushRadius(size.getBlockZ()); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin), "worldedit.brush.clipboard"); + + player.print("Clipboard brush shape equipped."); + } + + @Command( + aliases = { "smooth" }, + usage = "[size] [iterations]", + flags = "n", + desc = "Choose the terrain softener brush", + help = + "Chooses the terrain softener brush.\n" + + "The -n flag makes it only consider naturally occurring blocks.", + min = 0, + max = 2 + ) + @CommandPermissions("worldedit.brush.smooth") + public void smoothBrush(Player player, LocalSession session, EditSession editSession, + @Optional("2") double radius, @Optional("4") int iterations, @Switch('n') + boolean naturalBlocksOnly) throws WorldEditException { + + worldEdit.checkMaxBrushRadius(radius); + + FawePlayer fp = FawePlayer.wrap(player); + FaweLimit limit = Settings.getLimit(fp); + iterations = Math.min(limit.MAX_ITERATIONS, iterations); + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new SmoothBrush(iterations, naturalBlocksOnly), "worldedit.brush.smooth"); + + player.print(String.format("Smooth brush equipped (%.0f x %dx, using " + (naturalBlocksOnly ? "natural blocks only" : "any block") + ").", + radius, iterations)); + } + + @Command( + aliases = { "ex", "extinguish" }, + usage = "[radius]", + desc = "Shortcut fire extinguisher brush", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.ex") + public void extinguishBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + Pattern fill = new BlockPattern(new BaseBlock(0)); + tool.setFill(fill); + tool.setSize(radius); + tool.setMask(new BlockMask(editSession, new BaseBlock(BlockID.FIRE))); + tool.setBrush(new SphereBrush(), "worldedit.brush.ex"); + + player.print(String.format("Extinguisher equipped (%.0f).", radius)); + } + + @Command( + aliases = { "gravity", "grav" }, + usage = "[radius]", + flags = "h", + desc = "Gravity brush", + help = + "This brush simulates the affect of gravity.\n" + + "The -h flag makes it affect blocks starting at the world's max y, " + + "instead of the clicked block's y + radius.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.gravity") + public void gravityBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, @Switch('h') boolean fromMaxY) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new GravityBrush(fromMaxY), "worldedit.brush.gravity"); + + player.print(String.format("Gravity brush equipped (%.0f).", + radius)); + } + + @Command( + aliases = { "butcher", "kill" }, + usage = "[radius]", + flags = "plangbtfr", + desc = "Butcher brush", + help = "Kills nearby mobs within the specified radius.\n" + + "Flags:\n" + + " -p also kills pets.\n" + + " -n also kills NPCs.\n" + + " -g also kills Golems.\n" + + " -a also kills animals.\n" + + " -b also kills ambient mobs.\n" + + " -t also kills mobs with name tags.\n" + + " -f compounds all previous flags.\n" + + " -r also destroys armor stands.\n" + + " -l currently does nothing.", + min = 0, + max = 1 + ) + @CommandPermissions("worldedit.brush.butcher") + public void butcherBrush(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { + LocalConfiguration config = worldEdit.getConfiguration(); + + double radius = args.argsLength() > 0 ? args.getDouble(0) : 5; + double maxRadius = config.maxBrushRadius; + // hmmmm not horribly worried about this because -1 is still rather efficient, + // the problem arises when butcherMaxRadius is some really high number but not infinite + // - original idea taken from https://github.com/sk89q/worldedit/pull/198#issuecomment-6463108 + if (player.hasPermission("worldedit.butcher")) { + maxRadius = Math.max(config.maxBrushRadius, config.butcherMaxRadius); + } + if (radius > maxRadius) { + player.printError("Maximum allowed brush radius: " + maxRadius); + return; + } + + CreatureButcher flags = new CreatureButcher(player); + flags.fromCommand(args); + + BrushTool tool = session.getBrushTool(player.getItemInHand()); + tool.setSize(radius); + tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher"); + + player.print(String.format("Butcher brush equipped (%.0f).", radius)); + } + + public static Class inject() { + return BrushCommands.class; + } +} \ No newline at end of file diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 17b327ca..e4947d6a 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -145,7 +145,7 @@ public class ClipboardCommands { Operations.completeLegacy(copy); session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData())); - player.print(region.getArea() + " block(s) were copied."); + player.print(region.getArea() + " block(s) were copied. Note: For faster copying use //lazycopy"); } @Command(