mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Various
Fixes #68 Fixes #69 Fixes #80 Fixes #70 Fixes #72 added heightmap brush
This commit is contained in:
parent
b9f2671166
commit
024d46be78
3
.gitignore
vendored
3
.gitignore
vendored
@ -20,5 +20,4 @@ gradle.log
|
||||
/bukkit/build
|
||||
/bukkit0/build
|
||||
/bukkit19/build
|
||||
/bukkit18/build
|
||||
/core/build
|
||||
/bukkit18/build
|
@ -248,8 +248,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'WorldGuard' not found. Worldguard features disabled.");
|
||||
}
|
||||
final Plugin plotmePlugin = Bukkit.getServer().getPluginManager().getPlugin("PlotMe");
|
||||
if ((plotmePlugin != null) && plotmePlugin.isEnabled()) {
|
||||
@ -259,8 +257,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'PlotMe' not found. PlotMe features disabled.");
|
||||
}
|
||||
final Plugin townyPlugin = Bukkit.getServer().getPluginManager().getPlugin("Towny");
|
||||
if ((townyPlugin != null) && townyPlugin.isEnabled()) {
|
||||
@ -270,8 +266,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'Towny' not found. Towny features disabled.");
|
||||
}
|
||||
final Plugin factionsPlugin = Bukkit.getServer().getPluginManager().getPlugin("Factions");
|
||||
if ((factionsPlugin != null) && factionsPlugin.isEnabled()) {
|
||||
@ -292,8 +286,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'Factions' not found. Factions features disabled.");
|
||||
}
|
||||
final Plugin residencePlugin = Bukkit.getServer().getPluginManager().getPlugin("Residence");
|
||||
if ((residencePlugin != null) && residencePlugin.isEnabled()) {
|
||||
@ -303,8 +295,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'Residence' not found. Factions features disabled.");
|
||||
}
|
||||
final Plugin griefpreventionPlugin = Bukkit.getServer().getPluginManager().getPlugin("GriefPrevention");
|
||||
if ((griefpreventionPlugin != null) && griefpreventionPlugin.isEnabled()) {
|
||||
@ -314,8 +304,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'GriefPrevention' not found. GriefPrevention features disabled.");
|
||||
}
|
||||
final Plugin preciousstonesPlugin = Bukkit.getServer().getPluginManager().getPlugin("PreciousStones");
|
||||
if ((preciousstonesPlugin != null) && preciousstonesPlugin.isEnabled()) {
|
||||
@ -325,8 +313,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
} catch (final Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Plugin 'PreciousStones' not found. PreciousStones features disabled.");
|
||||
}
|
||||
return managers;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ jar.enabled = false
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency(':bukkit0'))
|
||||
include(dependency(':core'))
|
||||
}
|
||||
archiveName = "${parent.name}-${project.name}.jar"
|
||||
destinationDir = file '../target'
|
||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import net.minecraft.server.v1_9_R1.Block;
|
||||
import net.minecraft.server.v1_9_R1.DataBits;
|
||||
import net.minecraft.server.v1_9_R1.DataPalette;
|
||||
@ -51,28 +50,29 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk> {
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
DataPaletteBlock paletteBlock = new DataPaletteBlock();
|
||||
// Clone palette
|
||||
DataPalette currentPalette = (DataPalette) fieldPalette.get(paletteBlock);
|
||||
DataPalette currentPalette = (DataPalette) fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
try {
|
||||
Method resize = DataPaletteBlock.class.getDeclaredMethod("b", int.class);
|
||||
resize.setAccessible(true);
|
||||
resize.invoke(paletteBlock, 128);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
current.a(128, null);
|
||||
}
|
||||
DataPaletteBlock paletteBlock = new DataPaletteBlock();
|
||||
currentPalette = (DataPalette) fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
throw new RuntimeException("Palette must be global!");
|
||||
}
|
||||
currentPalette = (DataPalette) fieldPalette.get(paletteBlock);
|
||||
fieldPalette.set(paletteBlock, currentPalette);
|
||||
// Clone size
|
||||
fieldSize.set(paletteBlock, fieldSize.get(current));
|
||||
// Clone pallete
|
||||
// Clone palette
|
||||
DataBits currentBits = (DataBits) fieldBits.get(current);
|
||||
DataBits newBits = new DataBits(1, 0);
|
||||
for (Field field : DataBits.class.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
field.set(newBits, field.get(currentBits));
|
||||
Object currentValue = field.get(currentBits);
|
||||
if (currentValue instanceof long[]) {
|
||||
currentValue = ((long[]) currentValue).clone();
|
||||
}
|
||||
field.set(newBits, currentValue);
|
||||
}
|
||||
fieldBits.set(paletteBlock, newBits);
|
||||
value.sectionPalettes[i] = paletteBlock;
|
||||
|
@ -43,8 +43,17 @@ import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], DataPaletteBlock> {
|
||||
|
||||
private IBlockData air;
|
||||
|
||||
public BukkitQueue_1_9_R1(final String world) {
|
||||
super(world);
|
||||
try {
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -315,9 +324,12 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
|
||||
char combinedId = array[FaweCache.CACHE_J[y][x][z]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
if (existing != air) {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
// TODO check existing
|
||||
nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
|
||||
continue;
|
||||
default:
|
||||
|
@ -24,6 +24,8 @@ 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.HistoryCommands;
|
||||
import com.sk89q.worldedit.command.RegionCommands;
|
||||
import com.sk89q.worldedit.command.SchematicCommands;
|
||||
import com.sk89q.worldedit.command.ScriptingCommands;
|
||||
import com.sk89q.worldedit.command.composition.SelectionCommand;
|
||||
@ -44,6 +46,7 @@ import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||
import com.sk89q.worldedit.history.change.EntityCreate;
|
||||
import com.sk89q.worldedit.history.change.EntityRemove;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import java.io.File;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
@ -174,6 +177,7 @@ public class Fawe {
|
||||
try {
|
||||
WEManager.IMP.managers.addAll(Fawe.this.IMP.getMaskManagers());
|
||||
WEManager.IMP.managers.add(new PlotSquaredFeature());
|
||||
Fawe.debug("Plugin 'PlotSquared' found. Using it now.");
|
||||
} catch (Throwable e) {}
|
||||
Fawe.this.worldedit = WorldEdit.getInstance();
|
||||
// Events
|
||||
@ -238,8 +242,12 @@ public class Fawe {
|
||||
SchematicCommands.inject();
|
||||
ScriptingCommands.inject();
|
||||
SelectionCommand.inject();
|
||||
RegionCommands.inject();
|
||||
HistoryCommands.inject();
|
||||
// Brushes
|
||||
GravityBrush.inject();
|
||||
// Selectors
|
||||
CuboidRegionSelector.inject();
|
||||
// Visitors
|
||||
BreadthFirstSearch.inject();
|
||||
DownwardVisitor.inject();
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
@ -15,7 +14,7 @@ public class Reload extends FaweCommand {
|
||||
@Override
|
||||
public boolean execute(final FawePlayer player, final String... args) {
|
||||
Fawe.get().setupConfigs();
|
||||
MainUtil.sendMessage(player, "&d" + BBC.PREFIX.s() + " Reloaded configuration");
|
||||
MainUtil.sendMessage(player, "Reloaded configuration");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class Rollback extends FaweCommand {
|
||||
}
|
||||
player.deleteMeta("rollback");
|
||||
final FaweLocation origin = player.getLocation();
|
||||
rollback(player, !player.hasPermission("fawe.rollback.deep"), Arrays.copyOfRange(args, 1, args.length), new RunnableVal<List<DiskStorageHistory>>() {
|
||||
rollback(player, true, Arrays.copyOfRange(args, 1, args.length), new RunnableVal<List<DiskStorageHistory>>() {
|
||||
@Override
|
||||
public void run(List<DiskStorageHistory> edits) {
|
||||
long total = 0;
|
||||
@ -94,7 +94,7 @@ public class Rollback extends FaweCommand {
|
||||
@Override
|
||||
public void run() {
|
||||
if (edits.size() == 0) {
|
||||
player.sendMessage("&d" + BBC.PREFIX.s() + " Rollback complete!");
|
||||
player.sendMessage("Rollback complete!");
|
||||
return;
|
||||
}
|
||||
DiskStorageHistory edit = edits.remove(0);
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.configuration.file.YamlConfiguration;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import java.io.File;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
@ -16,14 +17,10 @@ public enum BBC {
|
||||
* Things to note about this class:
|
||||
* Can use multiple arguments %s, %s1, %s2, %s3 etc
|
||||
*/
|
||||
PREFIX("[FAWE]", "Info"),
|
||||
COMMAND_SYNTAX("&cUsage: &7%s0", "Error"),
|
||||
NO_PERM("&cYou are lacking the permission node: %s0", "Error"),
|
||||
SCHEMATIC_NOT_FOUND("&cSchematic not found: &7%s0", "Error"),
|
||||
PREFIX("&8(&5&lFAWE&8)&7", "Info"),
|
||||
SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"),
|
||||
FIX_LIGHTING_CHUNK("&7Lighting has been fixed in your current chunk. Relog to see the affect.", "Info"),
|
||||
FIX_LIGHTING_SELECTION("&7Lighting has been fixed in %s0 chunks. Relog to see the affect.", "Info"),
|
||||
NO_REGION("&cYou have no current WorldEdit region", "Error"),
|
||||
SET_REGION("&7Selection set to your current WorldEdit region", "Info"),
|
||||
WORLDEDIT_COMMAND_LIMIT("&7Please wait until your current action completes", "Info"),
|
||||
WORLDEDIT_DELAYED("&7Please wait while we process your WorldEdit action...", "Info"),
|
||||
@ -39,6 +36,76 @@ public enum BBC {
|
||||
WORLDEDIT_BYPASSED("&7Currently bypassing WorldEdit restriction.", "Info"),
|
||||
WORLDEDIT_UNMASKED("&6Your WorldEdit is now unrestricted.", "Info"),
|
||||
WORLDEDIT_RESTRICTED("&6Your WorldEdit is now restricted.", "Info"),
|
||||
WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable this safeguard", "Info"),
|
||||
COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"),
|
||||
ACTION_COMPLETE("Action completed in %s0 seconds", "Info"),
|
||||
|
||||
COMMAND_COPY("%s0 blocks were copied", "WorldEdit.Copy"),
|
||||
COMMAND_PASTE("The clipboard has been pasted at %s0", "WorldEdit.Paste"),
|
||||
COMMAND_ROTATE("The clipboard has been rotated", "WorldEdit.Rotate"),
|
||||
COMMAND_FLIPPED("The clipboard has been flipped", "WorldEdit.Flip"),
|
||||
COMMAND_REGEN("Region regenerated.", "WorldEdit.Regen"),
|
||||
COMMAND_TREE("%s0 trees created.", "WorldEdit.Tree"),
|
||||
COMMAND_FLORA("%s0 flora created.", "WorldEdit.Flora"),
|
||||
COMMAND_HISTORY_CLEAR("History cleared", "WorldEdit.History"),
|
||||
COMMAND_REDO_FAIL("Nothing left to redo.", "WorldEdit.History"),
|
||||
COMMAND_REDO_SUCCESS("Redo successful.", "WorldEdit.History"),
|
||||
COMMAND_UNDO_FAIL("Nothing left to undo.", "WorldEdit.History"),
|
||||
COMMAND_UNDO_SUCCESS("Undo successful.", "WorldEdit.History"),
|
||||
|
||||
OPERATION("Operation complete (%s0)", "WorldEdit.Operation"),
|
||||
|
||||
SELECTION_WAND("Left click: select pos #1; Right click: select pos #2", "WorldEdit.Selection"),
|
||||
SELECTION_WAND_DISABLE("Edit wand disabled.", "WorldEdit.Selection"),
|
||||
SELECTION_WAND_ENABLE("Edit wand enabled.", "WorldEdit.Selection"),
|
||||
SELECTION_CHUNK("Chunk selected (%s0)", "WorldEdit.Selection"),
|
||||
SELECTION_CHUNKS("Chunks selected (%s0) - (%s1)", "WorldEdit.Selection"),
|
||||
SELECTION_CONTRACT("Region contracted %s0 blocks.", "WorldEdit.Selection"),
|
||||
SELECTION_COUNT("Counted %s0 blocks.", "WorldEdit.Selection"),
|
||||
SELECTION_DISTR("# total blocks: %s0", "WorldEdit.Selection"),
|
||||
SELECTION_EXPAND("Region expanded %s0 blocks", "WorldEdit.Selection"),
|
||||
SELECTION_EXPAND_VERT("Region expanded %s0 blocks (top to bottom)", "WorldEdit.Selection"),
|
||||
SELECTION_INSET("Region inset", "WorldEdit.Selection"),
|
||||
SELECTION_OUTSET("Region outset", "WorldEdit.Selection"),
|
||||
SELECTION_SHIFT("Region shifted", "WorldEdit.Selection"),
|
||||
SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"),
|
||||
|
||||
BRUSH_BUTCHER("Butcher brush equiped (%s0)", "WorldEdit.Brush"),
|
||||
BRUSH_CLIPBOARD("Clipboard brush shape equipped", "WorldEdit.Brush"),
|
||||
BRUSH_CYLINDER("Cylinder brush shape equipped (%s0 by %s1).", "WorldEdit.Brush"),
|
||||
BRUSH_EXTINGUISHER("Extinguisher equipped (%s0).", "WorldEdit.Brush"),
|
||||
BRUSH_GRAVITY("Gravity brush equipped (%s0)", "WorldEdit.Brush"),
|
||||
BRUSH_HEIGHT("Height brush equipped (%s0)", "WorldEdit.Brush"),
|
||||
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
||||
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2).", "WorldEdit.Brush"),
|
||||
BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
|
||||
|
||||
SCHEMATIC_DELETE("%s0 has been deleted.", "Worldedit.Schematic"),
|
||||
SCHEMATIC_FORMAT("Available clipboard formats (Name: Lookup names)", "Worldedit.Schematic"),
|
||||
SCHEMATIC_LIST("Available schematics (Filename (Format)):", "Worldedit.Schematic"),
|
||||
SCHEMATIC_LOADED("%s0 loaded. Paste it with //paste", "Worldedit.Schematic"),
|
||||
SCHEMATIC_SAVED("%s0 saved.", "Worldedit.Schematic"),
|
||||
|
||||
CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"),
|
||||
|
||||
VISITOR_BLOCK("%s0 blocks affected", "WorldEdit.Visitor"),
|
||||
VISITOR_ENTITY("%s0 entities affected", "WorldEdit.Visitor"),
|
||||
VISITOR_FLAT("%s0 columns affected", "WorldEdit.Visitor"),
|
||||
|
||||
SELECTOR_CUBOID_POS1("First position set to %s0 %s1.", "WorldEdit.Selector"),
|
||||
SELECTOR_CUBOID_POS2("Second position set to %s0 %s1.", "WorldEdit.Selector"),
|
||||
|
||||
|
||||
|
||||
COMMAND_SYNTAX("&cUsage: &7%s0", "Error"),
|
||||
NO_PERM("&cYou are lacking the permission node: %s0", "Error"),
|
||||
SCHEMATIC_NOT_FOUND("&cSchematic not found: &7%s0", "Error"),
|
||||
NO_REGION("&cYou have no current WorldEdit region", "Error"),
|
||||
NOT_PLAYER("&cYou must be a player to perform this action!", "Error"),
|
||||
OOM(
|
||||
"&8[&cCritical&8] &cDetected low memory i.e. < 1%. FAWE will take the following actions:\n&8 - &7Terminate WE block placement\n&8 - &7Clear WE history\n&8 - &7Unload non essential chunks\n&8 - &7Kill entities\n&8 - &7Garbage collect\n&cIgnore this if trying to crash server.\n&7Note: Low memory is likely (but not necessarily) caused by WE",
|
||||
"Error"),
|
||||
|
||||
WORLDEDIT_CANCEL_COUNT("&cCancelled %s0 edits.", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"),
|
||||
WORLDEDIT_CANCEL_REASON_MANUAL("Manual cancellation", "Cancel"),
|
||||
@ -51,16 +118,15 @@ public enum BBC {
|
||||
WORLDEDIT_CANCEL_REASON_MAX_FAILS("Outside allowed region", "Cancel"),
|
||||
WORLDEDIT_FAILED_LOAD_CHUNK("&cSkipped loading chunk: &7%s0;%s1&c. Try increasing chunk-wait.", "Cancel"),
|
||||
|
||||
LOADING_CLIPBOARD("&dLoading clipboard from disk, please wait.", "History"),
|
||||
INDEXING_HISTORY("&dIndexing %s history objects on disk, please wait.", "History"),
|
||||
INDEXING_COMPLETE("&dIndexing complete. Took: %s seconds!", "History"),
|
||||
LOADING_CLIPBOARD("Loading clipboard from disk, please wait.", "History"),
|
||||
INDEXING_HISTORY("Indexing %s history objects on disk, please wait.", "History"),
|
||||
INDEXING_COMPLETE("Indexing complete. Took: %s seconds!", "History"),
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
|
||||
WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable this safeguard", "Info"),
|
||||
NOT_PLAYER("&cYou must be a player to perform this action!", "Error"),
|
||||
COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"),
|
||||
OOM(
|
||||
"&8[&cCritical&8] &cDetected low memory i.e. < 1%. FAWE will take the following actions:\n&8 - &7Terminate WE block placement\n&8 - &7Clear WE history\n&8 - &7Unload non essential chunks\n&8 - &7Kill entities\n&8 - &7Garbage collect\n&cIgnore this if trying to crash server.\n&7Note: Low memory is likely (but not necessarily) caused by WE",
|
||||
"Error");
|
||||
|
||||
private static final HashMap<String, String> replacements = new HashMap<>();
|
||||
/**
|
||||
@ -194,6 +260,19 @@ public enum BBC {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return s();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return length() == 0;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return toString().length();
|
||||
}
|
||||
|
||||
public static String color(String string) {
|
||||
return StringMan.replaceFromMap(string, replacements);
|
||||
}
|
||||
@ -210,11 +289,25 @@ public enum BBC {
|
||||
return this.cat;
|
||||
}
|
||||
|
||||
public void send(final FawePlayer<?> player, final Object... args) {
|
||||
if (player == null) {
|
||||
Fawe.debug(this.format(args));
|
||||
public void send(Actor actor, final Object... args) {
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (actor == null) {
|
||||
Fawe.debug((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
||||
} else {
|
||||
player.sendMessage(this.format(args));
|
||||
actor.print((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
||||
}
|
||||
}
|
||||
|
||||
public void send(final FawePlayer<?> player, final Object... args) {
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (player == null) {
|
||||
Fawe.debug((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
||||
} else {
|
||||
player.sendMessage((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
total += Math.min(4096, this.count[i]);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public abstract class FawePlayer<T> {
|
||||
}
|
||||
} catch (EmptyClipboardException e) {}
|
||||
if (player != null && session != null) {
|
||||
sendMessage("&d" + BBC.PREFIX.s() + " " + BBC.LOADING_CLIPBOARD.s());
|
||||
BBC.LOADING_CLIPBOARD.send(this);
|
||||
WorldData worldData = player.getWorld().getWorldData();
|
||||
Clipboard clip = doc.toClipboard();
|
||||
ClipboardHolder holder = new ClipboardHolder(clip, worldData);
|
||||
@ -162,7 +162,7 @@ public abstract class FawePlayer<T> {
|
||||
}
|
||||
}
|
||||
if (editIds.size() > 0) {
|
||||
sendMessage("&d" + BBC.PREFIX.s() + " " + BBC.INDEXING_HISTORY.format(editIds.size()));
|
||||
BBC.INDEXING_HISTORY.send(this, editIds.size());
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -177,7 +177,7 @@ public abstract class FawePlayer<T> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendMessage("&d" + BBC.PREFIX.s() + " " + BBC.INDEXING_COMPLETE.format((System.currentTimeMillis() - start) / 1000d));
|
||||
BBC.INDEXING_COMPLETE.send(FawePlayer.this, (System.currentTimeMillis() - start) / 1000d);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -28,7 +28,14 @@ public class NullChangeSet implements FaweChangeSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {}
|
||||
public boolean flush() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompressedSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Vector location, BaseBlock from, BaseBlock to) {}
|
||||
|
110
core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java
Normal file
110
core/src/main/java/com/boydti/fawe/object/brush/HeightBrush.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.brush.heightmap.ArrayHeightMap;
|
||||
import com.boydti.fawe.object.brush.heightmap.HeightMap;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class HeightBrush implements Brush {
|
||||
|
||||
public final HeightMap heightMap;
|
||||
private final int rotation;
|
||||
double yscale = 1;
|
||||
|
||||
public HeightBrush(File file, int rotation, double yscale) {
|
||||
this.rotation = (rotation / 90) % 4;
|
||||
this.yscale = yscale;
|
||||
if (file == null || !file.exists()) {
|
||||
heightMap = new HeightMap();
|
||||
} else {
|
||||
try {
|
||||
BufferedImage heightFile = ImageIO.read(file);
|
||||
int width = heightFile.getWidth();
|
||||
int length = heightFile.getHeight();
|
||||
Raster data = heightFile.getData();
|
||||
byte[][] array = new byte[width][length];
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
int pixel = heightFile.getRGB(x, z);
|
||||
int red = (pixel >> 16) & 0xFF;
|
||||
int green = (pixel >> 8) & 0xFF;
|
||||
int blue = (pixel >> 0) & 0xFF;
|
||||
int intensity = (red + green + blue) / 3;
|
||||
array[x][z] = (byte) intensity;
|
||||
}
|
||||
}
|
||||
heightMap = new ArrayHeightMap(array);
|
||||
} catch (IOException e) {
|
||||
throw new FaweException(BBC.BRUSH_HEIGHT_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
|
||||
int size = (int) sizeDouble;
|
||||
heightMap.setSize(size);
|
||||
|
||||
int size2 = size * size;
|
||||
int startY = position.getBlockY() + size;
|
||||
int endY = position.getBlockY() - size;
|
||||
int cx = position.getBlockX();
|
||||
int cz = position.getBlockZ();
|
||||
Vector mutablePos = new Vector(0, 0, 0);
|
||||
for (int x = -size; x <= size; x++) {
|
||||
int xx = cx + x;
|
||||
for (int z = -size; z <= size; z++) {
|
||||
int zz = cz + z;
|
||||
int raise;
|
||||
switch (rotation) {
|
||||
default:
|
||||
raise = heightMap.getHeight(x, z);
|
||||
break;
|
||||
case 1:
|
||||
raise = heightMap.getHeight(z, x);
|
||||
break;
|
||||
case 2:
|
||||
raise = heightMap.getHeight(-x, -z);
|
||||
break;
|
||||
case 3:
|
||||
raise = heightMap.getHeight(-z, -x);
|
||||
break;
|
||||
}
|
||||
raise = (int) (yscale * raise);
|
||||
if (raise == 0) {
|
||||
continue;
|
||||
}
|
||||
int foundHeight = Integer.MAX_VALUE;
|
||||
BaseBlock block = null;
|
||||
for (int y = startY; y >= endY; y--) {
|
||||
block = editSession.getLazyBlock(xx, y, zz);
|
||||
if (block != EditSession.nullBlock) {
|
||||
foundHeight = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundHeight == Integer.MAX_VALUE) {
|
||||
continue;
|
||||
}
|
||||
for (int y = foundHeight + 1; y <= foundHeight + raise; y++) {
|
||||
mutablePos.x = xx;
|
||||
mutablePos.y = y;
|
||||
mutablePos.z = zz;
|
||||
editSession.setBlock(mutablePos, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.boydti.fawe.object.brush.heightmap;
|
||||
|
||||
public class ArrayHeightMap extends HeightMap {
|
||||
// The heights
|
||||
private final byte[][] height;
|
||||
// The height map width/length
|
||||
private final int width, length;
|
||||
// The size to width/length ratio
|
||||
private double rx,rz;
|
||||
|
||||
public ArrayHeightMap(byte[][] height) {
|
||||
setSize(5);
|
||||
this.height = height;
|
||||
this.width = height.length;
|
||||
this.length = height[0].length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(int size) {
|
||||
super.setSize(size);
|
||||
this.rx = (double) width / (size << 1);
|
||||
this.rz = (double) width / (size << 1);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int x, int z) {
|
||||
x = (int) Math.max(0, Math.min(width - 1, (x + size) * rx));
|
||||
z = (int) Math.max(0, Math.min(length - 1, (z + size) * rz));
|
||||
return (((int) height[x][z] & 0xFF) * size) / 256;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.boydti.fawe.object.brush.heightmap;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
|
||||
public class HeightMap {
|
||||
public int size2;
|
||||
public int size;
|
||||
|
||||
public HeightMap() {
|
||||
setSize(5);
|
||||
}
|
||||
|
||||
public HeightMap(int size) {
|
||||
setSize(size);
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
this.size2 = size * size;
|
||||
}
|
||||
|
||||
public int getHeight(int x, int z) {
|
||||
int dx = Math.abs(x);
|
||||
int dz = Math.abs(z);
|
||||
int d2 = dx * dx + dz * dz;
|
||||
if (d2 > size2) {
|
||||
return 0;
|
||||
}
|
||||
return size - MathMan.sqrt(d2);
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ package com.boydti.fawe.object.changeset;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.IntegerPair;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
@ -96,7 +95,7 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
private int ox;
|
||||
private int oz;
|
||||
|
||||
private AtomicInteger size = new AtomicInteger();
|
||||
private int size;
|
||||
private World world;
|
||||
|
||||
public void deleteFiles() {
|
||||
@ -108,7 +107,6 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
}
|
||||
|
||||
public DiskStorageHistory(World world, UUID uuid) {
|
||||
size = new AtomicInteger();
|
||||
String base = "history" + File.separator + world.getName() + File.separator + uuid;
|
||||
File folder = new File(Fawe.imp().getDirectory(), base);
|
||||
int max = 0;
|
||||
@ -159,29 +157,32 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
|
||||
@Override
|
||||
public void add(Change change) {
|
||||
size.incrementAndGet();
|
||||
if ((change instanceof BlockChange)) {
|
||||
add((BlockChange) change);
|
||||
} else {
|
||||
Fawe.debug(BBC.PREFIX.s() + "Does not support " + change + " yet! (Please bug Empire92)");
|
||||
Fawe.debug("Does not support " + change + " yet! (Please bug Empire92)");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
public boolean flush() {
|
||||
boolean flushed = false;
|
||||
try {
|
||||
if (osBD != null) {
|
||||
flushed = true;
|
||||
osBD.flush();
|
||||
osBD.close();
|
||||
osBD = null;
|
||||
}
|
||||
if (osNBTF != null) {
|
||||
flushed = true;
|
||||
osNBTFG.flush();
|
||||
osNBTF.close();
|
||||
osNBTF = null;
|
||||
osNBTFG = null;
|
||||
}
|
||||
if (osNBTT != null) {
|
||||
flushed = true;
|
||||
osNBTTG.flush();
|
||||
osNBTT.close();
|
||||
osNBTT = null;
|
||||
@ -190,10 +191,17 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return flushed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCompressedSize() {
|
||||
return bdFile.exists() ? (int) bdFile.length() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int x, int y, int z, int combinedFrom, int combinedTo) {
|
||||
size++;
|
||||
try {
|
||||
OutputStream stream = getBAOS(x, y, z);
|
||||
//x
|
||||
@ -548,7 +556,7 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet {
|
||||
@Override
|
||||
public int size() {
|
||||
flush();
|
||||
return size.get();
|
||||
return size;
|
||||
}
|
||||
|
||||
public static class DiskStorageSummary {
|
||||
|
@ -5,7 +5,9 @@ import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
|
||||
public interface FaweChangeSet extends ChangeSet {
|
||||
void flush();
|
||||
boolean flush();
|
||||
|
||||
int getCompressedSize();
|
||||
|
||||
void add(Vector location, BaseBlock from, BaseBlock to);
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.boydti.fawe.object.changeset;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
@ -281,43 +279,26 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
public boolean flush() {
|
||||
if (idsStreamZip != null) {
|
||||
try {
|
||||
idsStream.flush();
|
||||
idsStreamZip.flush();
|
||||
idsStreamZip.close();
|
||||
ids = idsStream.toByteArray();
|
||||
/*
|
||||
* BlockVector
|
||||
* - reference to the object --> 8 bytes
|
||||
* - object header (java internals) --> 8 bytes
|
||||
* - double x, y, z --> 24 bytes
|
||||
*
|
||||
* BaseBlock
|
||||
* - reference to the object --> 8 bytes
|
||||
* - object header (java internals) --> 8 bytes
|
||||
* - short id, data --> 4 bytes
|
||||
* - NBTCompound (assuming null) --> 4 bytes
|
||||
*
|
||||
* There are usually two lists for the block changes:
|
||||
* 2 * BlockVector + 2 * BaseBlock = 128b
|
||||
*
|
||||
* This compares FAWE's usage to standard WE.
|
||||
*/
|
||||
int total = 128 * size;
|
||||
int current = ids.length + 16;
|
||||
int ratio = total / current;
|
||||
int saved = total - current;
|
||||
if (ratio > 3 && Thread.currentThread() != Fawe.get().getMainThread() && actor != null && actor.isPlayer() && actor.getSessionKey().isActive() && BBC.COMPRESSED.s().length() > 0) {
|
||||
actor.print(BBC.PREFIX.s() + " " + BBC.COMPRESSED.format(saved, ratio));
|
||||
}
|
||||
idsStream = null;
|
||||
idsStreamZip = null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getCompressedSize() {
|
||||
return ids == null ? 0 : ids.length;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public abstract class FaweQueue {
|
||||
try {
|
||||
return getCombinedId4Data(x, y, z);
|
||||
} catch (FaweException ignore) {
|
||||
session.debug(BBC.WORLDEDIT_FAILED_LOAD_CHUNK.format(x >> 4, z >> 4));
|
||||
session.debug(BBC.WORLDEDIT_FAILED_LOAD_CHUNK, x >> 4, z >> 4);
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,12 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.EndTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Map;
|
||||
@ -37,6 +39,44 @@ public class MainUtil {
|
||||
Fawe.debug(s);
|
||||
}
|
||||
|
||||
public static void sendCompressedMessage(FaweChangeSet set, Actor actor)
|
||||
{
|
||||
try {
|
||||
int elements = set.size();
|
||||
int compressedSize = set.getCompressedSize();
|
||||
/*
|
||||
* BlockVector
|
||||
* - reference to the object --> 8 bytes
|
||||
* - object header (java internals) --> 8 bytes
|
||||
* - double x, y, z --> 24 bytes
|
||||
*
|
||||
* BaseBlock
|
||||
* - reference to the object --> 8 bytes
|
||||
* - object header (java internals) --> 8 bytes
|
||||
* - short id, data --> 4 bytes
|
||||
* - NBTCompound (assuming null) --> 4 bytes
|
||||
*
|
||||
* There are usually two lists for the block changes:
|
||||
* 2 * BlockVector + 2 * BaseBlock = 128b
|
||||
*
|
||||
* WE has a lot more overhead, this is just a generous lower bound
|
||||
*
|
||||
* This compares FAWE's usage to standard WE.
|
||||
*/
|
||||
int total = 128 * elements;
|
||||
int current = compressedSize;
|
||||
|
||||
int ratio = total / current;
|
||||
int saved = total - current;
|
||||
|
||||
if (ratio > 3 && Thread.currentThread() != Fawe.get().getMainThread() && actor != null && actor.isPlayer() && actor.getSessionKey().isActive()) {
|
||||
BBC.COMPRESSED.send(actor, saved, ratio);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void warnDeprecated(Class... alternatives) {
|
||||
StackTraceElement[] stack = new RuntimeException().getStackTrace();
|
||||
if (stack.length > 1) {
|
||||
|
@ -21,6 +21,96 @@ public class MathMan {
|
||||
}
|
||||
}
|
||||
|
||||
private final static int[] table = {
|
||||
0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57,
|
||||
59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83,
|
||||
84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102,
|
||||
103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
|
||||
119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
|
||||
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
|
||||
146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
|
||||
158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
|
||||
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
|
||||
179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
|
||||
189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
|
||||
198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
|
||||
207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
|
||||
215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
|
||||
224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
|
||||
231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
|
||||
239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
|
||||
246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
|
||||
253, 254, 254, 255
|
||||
};
|
||||
|
||||
public static int sqrt(int x) {
|
||||
int xn;
|
||||
|
||||
if (x >= 0x10000) {
|
||||
if (x >= 0x1000000) {
|
||||
if (x >= 0x10000000) {
|
||||
if (x >= 0x40000000) {
|
||||
xn = table[x >> 24] << 8;
|
||||
} else {
|
||||
xn = table[x >> 22] << 7;
|
||||
}
|
||||
} else {
|
||||
if (x >= 0x4000000) {
|
||||
xn = table[x >> 20] << 6;
|
||||
} else {
|
||||
xn = table[x >> 18] << 5;
|
||||
}
|
||||
}
|
||||
|
||||
xn = (xn + 1 + (x / xn)) >> 1;
|
||||
xn = (xn + 1 + (x / xn)) >> 1;
|
||||
return ((xn * xn) > x) ? --xn : xn;
|
||||
} else {
|
||||
if (x >= 0x100000) {
|
||||
if (x >= 0x400000) {
|
||||
xn = table[x >> 16] << 4;
|
||||
} else {
|
||||
xn = table[x >> 14] << 3;
|
||||
}
|
||||
} else {
|
||||
if (x >= 0x40000) {
|
||||
xn = table[x >> 12] << 2;
|
||||
} else {
|
||||
xn = table[x >> 10] << 1;
|
||||
}
|
||||
}
|
||||
|
||||
xn = (xn + 1 + (x / xn)) >> 1;
|
||||
|
||||
return ((xn * xn) > x) ? --xn : xn;
|
||||
}
|
||||
} else {
|
||||
if (x >= 0x100) {
|
||||
if (x >= 0x1000) {
|
||||
if (x >= 0x4000) {
|
||||
xn = (table[x >> 8]) + 1;
|
||||
} else {
|
||||
xn = (table[x >> 6] >> 1) + 1;
|
||||
}
|
||||
} else {
|
||||
if (x >= 0x400) {
|
||||
xn = (table[x >> 4] >> 2) + 1;
|
||||
} else {
|
||||
xn = (table[x >> 2] >> 3) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ((xn * xn) > x) ? --xn : xn;
|
||||
} else {
|
||||
if (x >= 0) {
|
||||
return table[x] >> 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid number:" + x);
|
||||
}
|
||||
|
||||
|
||||
public static double getMean(int[] array) {
|
||||
double count = 0;
|
||||
for (int i : array) {
|
||||
|
@ -359,10 +359,8 @@ public class EditSession implements Extent {
|
||||
return;
|
||||
}
|
||||
|
||||
public void debug(String message) {
|
||||
if (actor != null && message != null && message.length() > 0) {
|
||||
actor.print(BBC.PREFIX.s() + " " + message);
|
||||
}
|
||||
public void debug(BBC message, Object... args) {
|
||||
message.send(actor, args);
|
||||
}
|
||||
|
||||
public FaweQueue getQueue() {
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.util.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.jchronic.Chronic;
|
||||
import com.sk89q.jchronic.Options;
|
||||
@ -217,7 +218,11 @@ public class LocalSession {
|
||||
}
|
||||
ChangeSet set = editSession.getChangeSet();
|
||||
if (set instanceof FaweChangeSet) {
|
||||
((FaweChangeSet) set).flush();
|
||||
FaweChangeSet fcs = (FaweChangeSet) set;
|
||||
if (fcs.flush() && append) {
|
||||
MainUtil.sendCompressedMessage(fcs, editSession.actor);
|
||||
}
|
||||
|
||||
}
|
||||
if (append) {
|
||||
history.add(editSession);
|
||||
|
@ -19,9 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.brush.HeightBrush;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
@ -51,6 +54,8 @@ 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 java.io.File;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -96,8 +101,7 @@ public class BrushCommands {
|
||||
} else {
|
||||
tool.setBrush(new SphereBrush(), "worldedit.brush.sphere");
|
||||
}
|
||||
|
||||
player.print(String.format("Sphere brush shape equipped (%.0f).", radius));
|
||||
BBC.BRUSH_SPHERE.send(player, radius);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -126,8 +130,7 @@ public class BrushCommands {
|
||||
} else {
|
||||
tool.setBrush(new CylinderBrush(height), "worldedit.brush.cylinder");
|
||||
}
|
||||
|
||||
player.print(String.format("Cylinder brush shape equipped (%.0f by %d).", radius, height));
|
||||
BBC.BRUSH_CYLINDER.send(player, radius, height);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -154,8 +157,7 @@ public class BrushCommands {
|
||||
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setBrush(new ClipboardBrush(holder, ignoreAir, usingOrigin), "worldedit.brush.clipboard");
|
||||
|
||||
player.print("Clipboard brush shape equipped.");
|
||||
BBC.BRUSH_CLIPBOARD.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -183,8 +185,7 @@ public class BrushCommands {
|
||||
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));
|
||||
BBC.BRUSH_SMOOTH.send(player, radius, iterations, (naturalBlocksOnly ? "natural blocks only" : "any block"));
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -204,8 +205,7 @@ public class BrushCommands {
|
||||
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));
|
||||
BBC.BRUSH_EXTINGUISHER.send(player, radius);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -227,9 +227,27 @@ public class BrushCommands {
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new GravityBrush(fromMaxY), "worldedit.brush.gravity");
|
||||
BBC.BRUSH_GRAVITY.send(player, radius);
|
||||
}
|
||||
|
||||
player.print(String.format("Gravity brush equipped (%.0f).",
|
||||
radius));
|
||||
@Command(
|
||||
aliases = { "height", "high" },
|
||||
usage = "[radius] [file] [rotation] [yscale]",
|
||||
flags = "h",
|
||||
desc = "Height brush",
|
||||
help =
|
||||
"This brush raises land.\n",
|
||||
min = 0,
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.height")
|
||||
public void heightBrush(Player player, LocalSession session, EditSession editSession, @Optional("5") double radius, @Optional("") final String filename, @Optional("0") final int rotation, @Optional("1") final double yscale) throws WorldEditException {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
File file = new File(Fawe.imp().getDirectory(), "heightmap" + File.separator + (filename.endsWith(".png") ? filename : filename + ".png"));
|
||||
BrushTool tool = session.getBrushTool(player.getItemInHand());
|
||||
tool.setSize(radius);
|
||||
tool.setBrush(new HeightBrush(file, rotation, yscale), "worldedit.brush.height");
|
||||
BBC.BRUSH_HEIGHT.send(player, radius);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -274,8 +292,7 @@ public class BrushCommands {
|
||||
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));
|
||||
BBC.BRUSH_BUTCHER.send(player, radius);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.clipboard.LazyClipboard;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
@ -135,7 +136,7 @@ public class ClipboardCommands {
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, lazyClipboard);
|
||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
|
||||
player.print(region.getArea() + " block(s) were not copied. I'll do it later, promise!");
|
||||
BBC.COMMAND_COPY.send(player, region.getArea());
|
||||
}
|
||||
|
||||
|
||||
@ -167,7 +168,7 @@ public class ClipboardCommands {
|
||||
Operations.completeLegacy(copy);
|
||||
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
|
||||
|
||||
player.print(region.getArea() + " block(s) were copied. Note: For faster copying use //lazycopy");
|
||||
BBC.COMMAND_COPY.send(player, region.getArea());
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -199,7 +200,7 @@ public class ClipboardCommands {
|
||||
Operations.completeLegacy(copy);
|
||||
session.setClipboard(new ClipboardHolder(clipboard, editSession.getWorld().getWorldData()));
|
||||
|
||||
player.print(region.getArea() + " block(s) were copied.");
|
||||
BBC.COMMAND_COPY.send(player, region.getArea());
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -244,8 +245,7 @@ public class ClipboardCommands {
|
||||
selector.learnChanges();
|
||||
selector.explainRegionAdjust(player, session);
|
||||
}
|
||||
|
||||
player.print("The clipboard has been pasted at " + to);
|
||||
BBC.COMMAND_PASTE.send(player, to);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -332,7 +332,7 @@ public class ClipboardCommands {
|
||||
selector.learnChanges();
|
||||
selector.explainRegionAdjust(player, session);
|
||||
}
|
||||
player.print("The clipboard has been placed at " + to);
|
||||
BBC.COMMAND_PASTE.send(player, to);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -357,7 +357,7 @@ public class ClipboardCommands {
|
||||
transform = transform.rotateX(-(xRotate != null ? xRotate : 0));
|
||||
transform = transform.rotateZ(-(zRotate != null ? zRotate : 0));
|
||||
holder.setTransform(holder.getTransform().combine(transform));
|
||||
player.print("The clipboard copy has been rotated.");
|
||||
BBC.COMMAND_ROTATE.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -377,7 +377,7 @@ public class ClipboardCommands {
|
||||
AffineTransform transform = new AffineTransform();
|
||||
transform = transform.scale(direction.positive().multiply(-2).add(1, 1, 1));
|
||||
holder.setTransform(holder.getTransform().combine(transform));
|
||||
player.print("The clipboard copy has been flipped.");
|
||||
BBC.COMMAND_FLIPPED.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -416,7 +416,7 @@ public class ClipboardCommands {
|
||||
@CommandPermissions("worldedit.clipboard.clear")
|
||||
public void clearClipboard(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
|
||||
session.setClipboard(null);
|
||||
player.print("Clipboard cleared.");
|
||||
BBC.CLIPBOARD_CLEARED.send(player);
|
||||
}
|
||||
public static Class<?> inject() {
|
||||
return ClipboardCommands.class;
|
||||
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
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.*;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Commands to undo, redo, and clear history.
|
||||
*/
|
||||
public class HistoryCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param worldEdit reference to WorldEdit
|
||||
*/
|
||||
public HistoryCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/undo", "undo" },
|
||||
usage = "[times] [player]",
|
||||
desc = "Undoes the last action",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.history.undo")
|
||||
public void undo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
int times = Math.max(1, args.getInteger(0, 1));
|
||||
for (int i = 0; i < times; ++i) {
|
||||
EditSession undone;
|
||||
if (args.argsLength() < 2) {
|
||||
undone = session.undo(session.getBlockBag(player), player);
|
||||
} else {
|
||||
player.checkPermission("worldedit.history.undo.other");
|
||||
LocalSession sess = worldEdit.getSession(args.getString(1));
|
||||
if (sess == null) {
|
||||
player.printError("Unable to find session for " + args.getString(1));
|
||||
break;
|
||||
}
|
||||
undone = sess.undo(session.getBlockBag(player), player);
|
||||
}
|
||||
if (undone != null) {
|
||||
BBC.COMMAND_UNDO_SUCCESS.send(player);
|
||||
worldEdit.flushBlockBag(player, undone);
|
||||
} else {
|
||||
BBC.COMMAND_UNDO_FAIL.send(player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/redo", "redo" },
|
||||
usage = "[times] [player]",
|
||||
desc = "Redoes the last action (from history)",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.history.redo")
|
||||
public void redo(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
int times = Math.max(1, args.getInteger(0, 1));
|
||||
|
||||
for (int i = 0; i < times; ++i) {
|
||||
EditSession redone;
|
||||
if (args.argsLength() < 2) {
|
||||
redone = session.redo(session.getBlockBag(player), player);
|
||||
} else {
|
||||
player.checkPermission("worldedit.history.redo.other");
|
||||
LocalSession sess = worldEdit.getSession(args.getString(1));
|
||||
if (sess == null) {
|
||||
player.printError("Unable to find session for " + args.getString(1));
|
||||
break;
|
||||
}
|
||||
redone = sess.redo(session.getBlockBag(player), player);
|
||||
}
|
||||
if (redone != null) {
|
||||
BBC.COMMAND_REDO_SUCCESS.send(player);
|
||||
worldEdit.flushBlockBag(player, redone);
|
||||
} else {
|
||||
BBC.COMMAND_REDO_FAIL.send(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/clearhistory", "clearhistory" },
|
||||
usage = "",
|
||||
desc = "Clear your history",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.history.clear")
|
||||
public void clearHistory(Player player, LocalSession session, EditSession editSession) throws WorldEditException {
|
||||
session.clearHistory();
|
||||
BBC.COMMAND_HISTORY_CLEAR.send(player);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return HistoryCommands.class;
|
||||
}
|
||||
}
|
@ -0,0 +1,483 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.minecraft.util.commands.Logging;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
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.entity.Player;
|
||||
import com.sk89q.worldedit.function.GroundFunction;
|
||||
import com.sk89q.worldedit.function.generator.FloraGenerator;
|
||||
import com.sk89q.worldedit.function.generator.ForestGenerator;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
import com.sk89q.worldedit.function.visitor.LayerVisitor;
|
||||
import com.sk89q.worldedit.internal.annotation.Direction;
|
||||
import com.sk89q.worldedit.internal.annotation.Selection;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.math.convolution.GaussianKernel;
|
||||
import com.sk89q.worldedit.math.convolution.HeightMap;
|
||||
import com.sk89q.worldedit.math.convolution.HeightMapFilter;
|
||||
import com.sk89q.worldedit.math.noise.RandomNoise;
|
||||
import com.sk89q.worldedit.regions.ConvexPolyhedralRegion;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionOperationException;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||
import com.sk89q.worldedit.util.command.binding.Range;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.binding.Text;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL;
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.ORIENTATION_REGION;
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
|
||||
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
|
||||
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
|
||||
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
||||
|
||||
/**
|
||||
* Commands that operate on regions.
|
||||
*/
|
||||
public class RegionCommands {
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param worldEdit reference to WorldEdit
|
||||
*/
|
||||
public RegionCommands(WorldEdit worldEdit) {
|
||||
checkNotNull(worldEdit);
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/line" },
|
||||
usage = "<block> [thickness]",
|
||||
desc = "Draws a line segment between cuboid selection corners",
|
||||
help =
|
||||
"Draws a line segment between cuboid selection corners.\n" +
|
||||
"Can only be used with cuboid selections.\n" +
|
||||
"Flags:\n" +
|
||||
" -h generates only a shell",
|
||||
flags = "h",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.line")
|
||||
@Logging(REGION)
|
||||
public void line(Player player, EditSession editSession,
|
||||
@Selection Region region,
|
||||
Pattern pattern,
|
||||
@Optional("0") @Range(min = 0) int thickness,
|
||||
@Switch('h') boolean shell) throws WorldEditException {
|
||||
|
||||
if (!(region instanceof CuboidRegion)) {
|
||||
player.printError("//line only works with cuboid selections");
|
||||
return;
|
||||
}
|
||||
|
||||
CuboidRegion cuboidregion = (CuboidRegion) region;
|
||||
Vector pos1 = cuboidregion.getPos1();
|
||||
Vector pos2 = cuboidregion.getPos2();
|
||||
int blocksChanged = editSession.drawLine(Patterns.wrap(pattern), pos1, pos2, thickness, !shell);
|
||||
|
||||
BBC.VISITOR_BLOCK.send(player, blocksChanged);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/curve" },
|
||||
usage = "<block> [thickness]",
|
||||
desc = "Draws a spline through selected points",
|
||||
help =
|
||||
"Draws a spline through selected points.\n" +
|
||||
"Can only be used with convex polyhedral selections.\n" +
|
||||
"Flags:\n" +
|
||||
" -h generates only a shell",
|
||||
flags = "h",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.curve")
|
||||
@Logging(REGION)
|
||||
public void curve(Player player, EditSession editSession,
|
||||
@Selection Region region,
|
||||
Pattern pattern,
|
||||
@Optional("0") @Range(min = 0) int thickness,
|
||||
@Switch('h') boolean shell) throws WorldEditException {
|
||||
if (!(region instanceof ConvexPolyhedralRegion)) {
|
||||
player.printError("//line only works with convex polyhedral selections");
|
||||
return;
|
||||
}
|
||||
|
||||
ConvexPolyhedralRegion cpregion = (ConvexPolyhedralRegion) region;
|
||||
List<Vector> vectors = new ArrayList<Vector>(cpregion.getVertices());
|
||||
|
||||
int blocksChanged = editSession.drawSpline(Patterns.wrap(pattern), vectors, 0, 0, 0, 10, thickness, !shell);
|
||||
|
||||
BBC.VISITOR_BLOCK.send(player, blocksChanged);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/replace", "/re", "/rep" },
|
||||
usage = "[from-block] <to-block>",
|
||||
desc = "Replace all blocks in the selection with another",
|
||||
flags = "f",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.replace")
|
||||
@Logging(REGION)
|
||||
public void replace(Player player, EditSession editSession, @Selection Region region, @Optional Mask from, Pattern to) throws WorldEditException {
|
||||
if (from == null) {
|
||||
from = new ExistingBlockMask(editSession);
|
||||
}
|
||||
int affected = editSession.replaceBlocks(region, from, Patterns.wrap(to));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/overlay" },
|
||||
usage = "<block>",
|
||||
desc = "Set a block on top of blocks in the region",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.overlay")
|
||||
@Logging(REGION)
|
||||
public void overlay(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
|
||||
int affected = editSession.overlayCuboidBlocks(region, Patterns.wrap(pattern));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/center", "/middle" },
|
||||
usage = "<block>",
|
||||
desc = "Set the center block(s)",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.region.center")
|
||||
public void center(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
|
||||
int affected = editSession.center(region, Patterns.wrap(pattern));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/naturalize" },
|
||||
usage = "",
|
||||
desc = "3 layers of dirt on top then rock below",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.region.naturalize")
|
||||
@Logging(REGION)
|
||||
public void naturalize(Player player, EditSession editSession, @Selection Region region) throws WorldEditException {
|
||||
int affected = editSession.naturalizeCuboidBlocks(region);
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/walls" },
|
||||
usage = "<block>",
|
||||
desc = "Build the four sides of the selection",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.walls")
|
||||
@Logging(REGION)
|
||||
public void walls(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
|
||||
int affected = editSession.makeCuboidWalls(region, Patterns.wrap(pattern));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/faces", "/outline" },
|
||||
usage = "<block>",
|
||||
desc = "Build the walls, ceiling, and floor of a selection",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.faces")
|
||||
@Logging(REGION)
|
||||
public void faces(Player player, EditSession editSession, @Selection Region region, Pattern pattern) throws WorldEditException {
|
||||
int affected = editSession.makeCuboidFaces(region, Patterns.wrap(pattern));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/smooth" },
|
||||
usage = "[iterations]",
|
||||
flags = "n",
|
||||
desc = "Smooth the elevation in the selection",
|
||||
help =
|
||||
"Smooths the elevation in the selection.\n" +
|
||||
"The -n flag makes it only consider naturally occuring blocks.",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.smooth")
|
||||
@Logging(REGION)
|
||||
public void smooth(Player player, EditSession editSession, @Selection Region region, @Optional("1") int iterations, @Switch('n') boolean affectNatural) throws WorldEditException {
|
||||
HeightMap heightMap = new HeightMap(editSession, region, affectNatural);
|
||||
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
|
||||
int affected = heightMap.applyFilter(filter, iterations);
|
||||
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/move" },
|
||||
usage = "[count] [direction] [leave-id]",
|
||||
flags = "s",
|
||||
desc = "Move the contents of the selection",
|
||||
help =
|
||||
"Moves the contents of the selection.\n" +
|
||||
"The -s flag shifts the selection to the target location.\n" +
|
||||
"Optionally fills the old location with <leave-id>.",
|
||||
min = 0,
|
||||
max = 3
|
||||
)
|
||||
@CommandPermissions("worldedit.region.move")
|
||||
@Logging(ORIENTATION_REGION)
|
||||
public void move(Player player, EditSession editSession, LocalSession session,
|
||||
@Selection Region region,
|
||||
@Optional("1") @Range(min = 1) int count,
|
||||
@Optional(Direction.AIM) @Direction Vector direction,
|
||||
@Optional("air") BaseBlock replace,
|
||||
@Switch('s') boolean moveSelection) throws WorldEditException {
|
||||
|
||||
int affected = editSession.moveRegion(region, direction, count, true, replace);
|
||||
|
||||
if (moveSelection) {
|
||||
try {
|
||||
region.shift(direction.multiply(count));
|
||||
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
} catch (RegionOperationException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/stack" },
|
||||
usage = "[count] [direction]",
|
||||
flags = "sa",
|
||||
desc = "Repeat the contents of the selection",
|
||||
help =
|
||||
"Repeats the contents of the selection.\n" +
|
||||
"Flags:\n" +
|
||||
" -s shifts the selection to the last stacked copy\n" +
|
||||
" -a skips air blocks",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.stack")
|
||||
@Logging(ORIENTATION_REGION)
|
||||
public void stack(Player player, EditSession editSession, LocalSession session,
|
||||
@Selection Region region,
|
||||
@Optional("1") @Range(min = 1) int count,
|
||||
@Optional(Direction.AIM) @Direction Vector direction,
|
||||
@Switch('s') boolean moveSelection,
|
||||
@Switch('a') boolean ignoreAirBlocks) throws WorldEditException {
|
||||
int affected = editSession.stackCuboidRegion(region, direction, count, !ignoreAirBlocks);
|
||||
|
||||
if (moveSelection) {
|
||||
try {
|
||||
final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
|
||||
|
||||
final Vector shiftVector = direction.multiply(count * (Math.abs(direction.dot(size)) + 1));
|
||||
region.shift(shiftVector);
|
||||
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
} catch (RegionOperationException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/regen" },
|
||||
usage = "",
|
||||
desc = "Regenerates the contents of the selection",
|
||||
help =
|
||||
"Regenerates the contents of the current selection.\n" +
|
||||
"This command might affect things outside the selection,\n" +
|
||||
"if they are within the same chunk.",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.regen")
|
||||
@Logging(REGION)
|
||||
public void regenerateChunk(Player player, LocalSession session, EditSession editSession, @Selection Region region) throws WorldEditException {
|
||||
Mask mask = session.getMask();
|
||||
try {
|
||||
session.setMask((Mask) null);
|
||||
player.getWorld().regenerate(region, editSession);
|
||||
} finally {
|
||||
session.setMask(mask);
|
||||
}
|
||||
BBC.COMMAND_REGEN.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/deform" },
|
||||
usage = "<expression>",
|
||||
desc = "Deforms a selected region with an expression",
|
||||
help =
|
||||
"Deforms a selected region with an expression\n" +
|
||||
"The expression is executed for each block and is expected\n" +
|
||||
"to modify the variables x, y and z to point to a new block\n" +
|
||||
"to fetch. See also tinyurl.com/wesyntax.",
|
||||
flags = "ro",
|
||||
min = 1,
|
||||
max = -1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.deform")
|
||||
@Logging(ALL)
|
||||
public void deform(Player player, LocalSession session, EditSession editSession,
|
||||
@Selection Region region,
|
||||
@Text String expression,
|
||||
@Switch('r') boolean useRawCoords,
|
||||
@Switch('o') boolean offset) throws WorldEditException {
|
||||
final Vector zero;
|
||||
Vector unit;
|
||||
|
||||
if (useRawCoords) {
|
||||
zero = Vector.ZERO;
|
||||
unit = Vector.ONE;
|
||||
} else if (offset) {
|
||||
zero = session.getPlacementPosition(player);
|
||||
unit = Vector.ONE;
|
||||
} else {
|
||||
final Vector min = region.getMinimumPoint();
|
||||
final Vector max = region.getMaximumPoint();
|
||||
|
||||
zero = max.add(min).multiply(0.5);
|
||||
unit = max.subtract(zero);
|
||||
|
||||
if (unit.getX() == 0) unit = unit.setX(1.0);
|
||||
if (unit.getY() == 0) unit = unit.setY(1.0);
|
||||
if (unit.getZ() == 0) unit = unit.setZ(1.0);
|
||||
}
|
||||
|
||||
try {
|
||||
final int affected = editSession.deformRegion(region, zero, unit, expression);
|
||||
player.findFreePosition();
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
} catch (ExpressionException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/hollow" },
|
||||
usage = "[<thickness>[ <block>]]",
|
||||
desc = "Hollows out the object contained in this selection",
|
||||
help =
|
||||
"Hollows out the object contained in this selection.\n" +
|
||||
"Optionally fills the hollowed out part with the given block.\n" +
|
||||
"Thickness is measured in manhattan distance.",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.hollow")
|
||||
@Logging(REGION)
|
||||
public void hollow(Player player, EditSession editSession,
|
||||
@Selection Region region,
|
||||
@Optional("0") @Range(min = 0) int thickness,
|
||||
@Optional("air") Pattern pattern) throws WorldEditException {
|
||||
|
||||
int affected = editSession.hollowOutRegion(region, thickness, Patterns.wrap(pattern));
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/forest" },
|
||||
usage = "[type] [density]",
|
||||
desc = "Make a forest within the region",
|
||||
min = 0,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.region.forest")
|
||||
@Logging(REGION)
|
||||
public void forest(Player player, EditSession editSession, @Selection Region region, @Optional("tree") TreeType type,
|
||||
@Optional("5") @Range(min = 0, max = 100) double density) throws WorldEditException {
|
||||
density = density / 100;
|
||||
ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type));
|
||||
GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator);
|
||||
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
|
||||
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
|
||||
Operations.completeLegacy(visitor);
|
||||
|
||||
BBC.COMMAND_TREE.send(player, ground.getAffected());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/flora" },
|
||||
usage = "[density]",
|
||||
desc = "Make flora within the region",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.region.flora")
|
||||
@Logging(REGION)
|
||||
public void flora(Player player, EditSession editSession, @Selection Region region, @Optional("10") @Range(min = 0, max = 100) double density) throws WorldEditException {
|
||||
density = density / 100;
|
||||
FloraGenerator generator = new FloraGenerator(editSession);
|
||||
GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator);
|
||||
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
|
||||
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
|
||||
Operations.completeLegacy(visitor);
|
||||
|
||||
BBC.COMMAND_FLORA.send(player, ground.getAffected());
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return RegionCommands.class;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
@ -119,7 +120,7 @@ public class SchematicCommands {
|
||||
}
|
||||
session.setClipboard(new ClipboardHolder(clipboard, worldData));
|
||||
log.info(player.getName() + " loaded " + filePath);
|
||||
player.print(filename + " loaded. Paste it with //paste");
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
player.printError("Schematic could not read or it does not exist: " + e.getMessage());
|
||||
@ -183,7 +184,7 @@ public class SchematicCommands {
|
||||
final ClipboardWriter writer = closer.register(format.getWriter(bos));
|
||||
writer.write(target, holder.getWorldData());
|
||||
log.info(player.getName() + " saved " + f.getCanonicalPath());
|
||||
player.print(filename + " saved.");
|
||||
BBC.SCHEMATIC_SAVED.send(player, filename);
|
||||
} catch (final IOException e) {
|
||||
player.printError("Schematic could not written: " + e.getMessage());
|
||||
log.log(Level.WARNING, "Failed to write a saved clipboard", e);
|
||||
@ -219,7 +220,7 @@ public class SchematicCommands {
|
||||
return;
|
||||
}
|
||||
|
||||
player.print(filename + " has been deleted.");
|
||||
BBC.SCHEMATIC_DELETE.send(player, filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -227,7 +228,7 @@ public class SchematicCommands {
|
||||
@Command(aliases = { "formats", "listformats", "f" }, desc = "List available formats", max = 0)
|
||||
@CommandPermissions("worldedit.schematic.formats")
|
||||
public void formats(final Actor actor) throws WorldEditException {
|
||||
actor.print("Available clipboard formats (Name: Lookup names)");
|
||||
BBC.SCHEMATIC_FORMAT.send(actor);
|
||||
StringBuilder builder;
|
||||
boolean first = true;
|
||||
for (final ClipboardFormat format : ClipboardFormat.values()) {
|
||||
@ -284,8 +285,7 @@ public class SchematicCommands {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
actor.print("Available schematics (Filename (Format)):");
|
||||
BBC.SCHEMATIC_LIST.send(actor);
|
||||
actor.print(this.listFiles("", files));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,795 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.google.common.base.Optional;
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.minecraft.util.commands.Logging;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionOperationException;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.RegionSelectorType;
|
||||
import com.sk89q.worldedit.regions.selector.SphereRegionSelector;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
|
||||
import com.sk89q.worldedit.util.formatting.Style;
|
||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION;
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION;
|
||||
|
||||
/**
|
||||
* Selection commands.
|
||||
*/
|
||||
public class SelectionCommands {
|
||||
|
||||
private final WorldEdit we;
|
||||
|
||||
public SelectionCommands(WorldEdit we) {
|
||||
this.we = we;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/pos1" },
|
||||
usage = "[coordinates]",
|
||||
desc = "Set position 1",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@Logging(POSITION)
|
||||
@CommandPermissions("worldedit.selection.pos")
|
||||
public void pos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
Vector pos;
|
||||
|
||||
if (args.argsLength() == 1) {
|
||||
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
|
||||
String[] coords = args.getString(0).split(",");
|
||||
pos = new Vector(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]), Integer.parseInt(coords[2]));
|
||||
} else {
|
||||
player.printError("Invalid coordinates " + args.getString(0));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pos = player.getBlockIn();
|
||||
}
|
||||
|
||||
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) {
|
||||
player.printError("Position already set.");
|
||||
return;
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld())
|
||||
.explainPrimarySelection(player, session, pos);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/pos2" },
|
||||
usage = "[coordinates]",
|
||||
desc = "Set position 2",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@Logging(POSITION)
|
||||
@CommandPermissions("worldedit.selection.pos")
|
||||
public void pos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
Vector pos;
|
||||
if (args.argsLength() == 1) {
|
||||
if (args.getString(0).matches("-?\\d+,-?\\d+,-?\\d+")) {
|
||||
String[] coords = args.getString(0).split(",");
|
||||
pos = new Vector(Integer.parseInt(coords[0]),
|
||||
Integer.parseInt(coords[1]),
|
||||
Integer.parseInt(coords[2]));
|
||||
} else {
|
||||
player.printError("Invalid coordinates " + args.getString(0));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pos = player.getBlockIn();
|
||||
}
|
||||
|
||||
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
|
||||
player.printError("Position already set.");
|
||||
return;
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld())
|
||||
.explainSecondarySelection(player, session, pos);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/hpos1" },
|
||||
usage = "",
|
||||
desc = "Set position 1 to targeted block",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.selection.hpos")
|
||||
public void hpos1(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
Vector pos = player.getBlockTrace(300);
|
||||
|
||||
if (pos != null) {
|
||||
if (!session.getRegionSelector(player.getWorld()).selectPrimary(pos, ActorSelectorLimits.forActor(player))) {
|
||||
player.printError("Position already set.");
|
||||
return;
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld())
|
||||
.explainPrimarySelection(player, session, pos);
|
||||
} else {
|
||||
player.printError("No block in sight!");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/hpos2" },
|
||||
usage = "",
|
||||
desc = "Set position 2 to targeted block",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.selection.hpos")
|
||||
public void hpos2(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
Vector pos = player.getBlockTrace(300);
|
||||
|
||||
if (pos != null) {
|
||||
if (!session.getRegionSelector(player.getWorld()).selectSecondary(pos, ActorSelectorLimits.forActor(player))) {
|
||||
player.printError("Position already set.");
|
||||
return;
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld())
|
||||
.explainSecondarySelection(player, session, pos);
|
||||
} else {
|
||||
player.printError("No block in sight!");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/chunk" },
|
||||
usage = "[x,z coordinates]",
|
||||
flags = "sc",
|
||||
desc = "Set the selection to your current chunk.",
|
||||
help =
|
||||
"Set the selection to the chunk you are currently in.\n" +
|
||||
"With the -s flag, your current selection is expanded\n" +
|
||||
"to encompass all chunks that are part of it.\n\n" +
|
||||
"Specifying coordinates will use those instead of your\n"+
|
||||
"current position. Use -c to specify chunk coordinates,\n" +
|
||||
"otherwise full coordinates will be implied.\n" +
|
||||
"(for example, the coordinates 5,5 are the same as -c 0,0)",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@Logging(POSITION)
|
||||
@CommandPermissions("worldedit.selection.chunk")
|
||||
public void chunk(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
final Vector min;
|
||||
final Vector max;
|
||||
final World world = player.getWorld();
|
||||
if (args.hasFlag('s')) {
|
||||
Region region = session.getSelection(world);
|
||||
|
||||
final Vector2D min2D = ChunkStore.toChunk(region.getMinimumPoint());
|
||||
final Vector2D max2D = ChunkStore.toChunk(region.getMaximumPoint());
|
||||
|
||||
min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
|
||||
max = new Vector(max2D.getBlockX() * 16 + 15, world.getMaxY(), max2D.getBlockZ() * 16 + 15);
|
||||
|
||||
BBC.SELECTION_CHUNKS.send(player, min2D.getBlockX() + ", " + min2D.getBlockZ(), max2D.getBlockX() + ", " + max2D.getBlockZ());
|
||||
} else {
|
||||
final Vector2D min2D;
|
||||
if (args.argsLength() == 1) {
|
||||
// coords specified
|
||||
String[] coords = args.getString(0).split(",");
|
||||
if (coords.length != 2) {
|
||||
throw new InsufficientArgumentsException("Invalid coordinates specified.");
|
||||
}
|
||||
int x = Integer.parseInt(coords[0]);
|
||||
int z = Integer.parseInt(coords[1]);
|
||||
Vector2D pos = new Vector2D(x, z);
|
||||
min2D = (args.hasFlag('c')) ? pos : ChunkStore.toChunk(pos.toVector());
|
||||
} else {
|
||||
// use player loc
|
||||
min2D = ChunkStore.toChunk(player.getBlockIn());
|
||||
}
|
||||
|
||||
min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
|
||||
max = min.add(15, world.getMaxY(), 15);
|
||||
|
||||
BBC.SELECTION_CHUNK.send(player, min2D.getBlockX() + ", " + min2D.getBlockZ());
|
||||
}
|
||||
|
||||
final CuboidRegionSelector selector;
|
||||
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) {
|
||||
selector = new ExtendingCuboidRegionSelector(world);
|
||||
} else {
|
||||
selector = new CuboidRegionSelector(world);
|
||||
}
|
||||
selector.selectPrimary(min, ActorSelectorLimits.forActor(player));
|
||||
selector.selectSecondary(max, ActorSelectorLimits.forActor(player));
|
||||
session.setRegionSelector(world, selector);
|
||||
|
||||
session.dispatchCUISelection(player);
|
||||
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/wand" },
|
||||
usage = "",
|
||||
desc = "Get the wand object",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.wand")
|
||||
public void wand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
player.giveItem(we.getConfiguration().wandItem, 1);
|
||||
BBC.SELECTION_WAND.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "toggleeditwand" },
|
||||
usage = "",
|
||||
desc = "Toggle functionality of the edit wand",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.wand.toggle")
|
||||
public void toggleWand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
session.setToolControl(!session.isToolControlEnabled());
|
||||
|
||||
if (session.isToolControlEnabled()) {
|
||||
BBC.SELECTION_WAND_ENABLE.send(player);
|
||||
} else {
|
||||
BBC.SELECTION_WAND_DISABLE.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/expand" },
|
||||
usage = "<amount> [reverse-amount] <direction>",
|
||||
desc = "Expand the selection area",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.selection.expand")
|
||||
public void expand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
// Special syntax (//expand vert) to expand the selection between
|
||||
// sky and bedrock.
|
||||
if (args.getString(0).equalsIgnoreCase("vert")
|
||||
|| args.getString(0).equalsIgnoreCase("vertical")) {
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
try {
|
||||
int oldSize = region.getArea();
|
||||
region.expand(
|
||||
new Vector(0, (player.getWorld().getMaxY() + 1), 0),
|
||||
new Vector(0, -(player.getWorld().getMaxY() + 1), 0));
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
BBC.SELECTION_EXPAND_VERT.send(player, (newSize - oldSize));
|
||||
} catch (RegionOperationException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
List<Vector> dirs = new ArrayList<Vector>();
|
||||
int change = args.getInteger(0);
|
||||
int reverseChange = 0;
|
||||
|
||||
switch (args.argsLength()) {
|
||||
case 2:
|
||||
// Either a reverse amount or a direction
|
||||
try {
|
||||
reverseChange = args.getInteger(1);
|
||||
dirs.add(we.getDirection(player, "me"));
|
||||
} catch (NumberFormatException e) {
|
||||
if (args.getString(1).contains(",")) {
|
||||
String[] split = args.getString(1).split(",");
|
||||
for (String s : split) {
|
||||
dirs.add(we.getDirection(player, s.toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, args.getString(1).toLowerCase()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Both reverse amount and direction
|
||||
reverseChange = args.getInteger(1);
|
||||
if (args.getString(2).contains(",")) {
|
||||
String[] split = args.getString(2).split(",");
|
||||
for (String s : split) {
|
||||
dirs.add(we.getDirection(player, s.toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, args.getString(2).toLowerCase()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dirs.add(we.getDirection(player, "me"));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
int oldSize = region.getArea();
|
||||
|
||||
if (reverseChange == 0) {
|
||||
for (Vector dir : dirs) {
|
||||
region.expand(dir.multiply(change));
|
||||
}
|
||||
} else {
|
||||
for (Vector dir : dirs) {
|
||||
region.expand(dir.multiply(change), dir.multiply(-reverseChange));
|
||||
}
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
BBC.SELECTION_EXPAND.send(player, (newSize - oldSize));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/contract" },
|
||||
usage = "<amount> [reverse-amount] [direction]",
|
||||
desc = "Contract the selection area",
|
||||
min = 1,
|
||||
max = 3
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.selection.contract")
|
||||
public void contract(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
List<Vector> dirs = new ArrayList<Vector>();
|
||||
int change = args.getInteger(0);
|
||||
int reverseChange = 0;
|
||||
|
||||
switch (args.argsLength()) {
|
||||
case 2:
|
||||
// Either a reverse amount or a direction
|
||||
try {
|
||||
reverseChange = args.getInteger(1);
|
||||
dirs.add(we.getDirection(player, "me"));
|
||||
} catch (NumberFormatException e) {
|
||||
if (args.getString(1).contains(",")) {
|
||||
String[] split = args.getString(1).split(",");
|
||||
for (String s : split) {
|
||||
dirs.add(we.getDirection(player, s.toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, args.getString(1).toLowerCase()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Both reverse amount and direction
|
||||
reverseChange = args.getInteger(1);
|
||||
if (args.getString(2).contains(",")) {
|
||||
String[] split = args.getString(2).split(",");
|
||||
for (String s : split) {
|
||||
dirs.add(we.getDirection(player, s.toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, args.getString(2).toLowerCase()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dirs.add(we.getDirection(player, "me"));
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
int oldSize = region.getArea();
|
||||
if (reverseChange == 0) {
|
||||
for (Vector dir : dirs) {
|
||||
region.contract(dir.multiply(change));
|
||||
}
|
||||
} else {
|
||||
for (Vector dir : dirs) {
|
||||
region.contract(dir.multiply(change), dir.multiply(-reverseChange));
|
||||
}
|
||||
}
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
|
||||
BBC.SELECTION_CONTRACT.send(player, (oldSize - newSize));
|
||||
} catch (RegionOperationException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/shift" },
|
||||
usage = "<amount> [direction]",
|
||||
desc = "Shift the selection area",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.selection.shift")
|
||||
public void shift(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
List<Vector> dirs = new ArrayList<Vector>();
|
||||
int change = args.getInteger(0);
|
||||
if (args.argsLength() == 2) {
|
||||
if (args.getString(1).contains(",")) {
|
||||
for (String s : args.getString(1).split(",")) {
|
||||
dirs.add(we.getDirection(player, s.toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, args.getString(1).toLowerCase()));
|
||||
}
|
||||
} else {
|
||||
dirs.add(we.getDirection(player, "me"));
|
||||
}
|
||||
|
||||
try {
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
|
||||
for (Vector dir : dirs) {
|
||||
region.shift(dir.multiply(change));
|
||||
}
|
||||
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
BBC.SELECTION_SHIFT.send(player);
|
||||
} catch (RegionOperationException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/outset" },
|
||||
usage = "<amount>",
|
||||
desc = "Outset the selection area",
|
||||
help =
|
||||
"Expands the selection by the given amount in all directions.\n" +
|
||||
"Flags:\n" +
|
||||
" -h only expand horizontally\n" +
|
||||
" -v only expand vertically\n",
|
||||
flags = "hv",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.selection.outset")
|
||||
public void outset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
region.expand(getChangesForEachDir(args));
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
BBC.SELECTION_OUTSET.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/inset" },
|
||||
usage = "<amount>",
|
||||
desc = "Inset the selection area",
|
||||
help =
|
||||
"Contracts the selection by the given amount in all directions.\n" +
|
||||
"Flags:\n" +
|
||||
" -h only contract horizontally\n" +
|
||||
" -v only contract vertically\n",
|
||||
flags = "hv",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@Logging(REGION)
|
||||
@CommandPermissions("worldedit.selection.inset")
|
||||
public void inset(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
region.contract(getChangesForEachDir(args));
|
||||
session.getRegionSelector(player.getWorld()).learnChanges();
|
||||
session.getRegionSelector(player.getWorld()).explainRegionAdjust(player, session);
|
||||
BBC.SELECTION_INSET.send(player);
|
||||
}
|
||||
|
||||
private Vector[] getChangesForEachDir(CommandContext args) {
|
||||
List<Vector> changes = new ArrayList<Vector>(6);
|
||||
int change = args.getInteger(0);
|
||||
|
||||
if (!args.hasFlag('h')) {
|
||||
changes.add((new Vector(0, 1, 0)).multiply(change));
|
||||
changes.add((new Vector(0, -1, 0)).multiply(change));
|
||||
}
|
||||
|
||||
if (!args.hasFlag('v')) {
|
||||
changes.add((new Vector(1, 0, 0)).multiply(change));
|
||||
changes.add((new Vector(-1, 0, 0)).multiply(change));
|
||||
changes.add((new Vector(0, 0, 1)).multiply(change));
|
||||
changes.add((new Vector(0, 0, -1)).multiply(change));
|
||||
}
|
||||
|
||||
return changes.toArray(new Vector[0]);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/size" },
|
||||
flags = "c",
|
||||
usage = "",
|
||||
desc = "Get information about the selection",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.selection.size")
|
||||
public void size(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
if (args.hasFlag('c')) {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
Region region = clipboard.getRegion();
|
||||
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
|
||||
Vector origin = clipboard.getOrigin();
|
||||
|
||||
player.print("Cuboid dimensions (max - min): " + size);
|
||||
player.print("Offset: " + origin);
|
||||
player.print("Cuboid distance: " + size.distance(Vector.ONE));
|
||||
player.print("# of blocks: " + (int) (size.getX() * size.getY() * size.getZ()));
|
||||
return;
|
||||
}
|
||||
|
||||
Region region = session.getSelection(player.getWorld());
|
||||
Vector size = region.getMaximumPoint()
|
||||
.subtract(region.getMinimumPoint())
|
||||
.add(1, 1, 1);
|
||||
|
||||
player.print("Type: " + session.getRegionSelector(player.getWorld())
|
||||
.getTypeName());
|
||||
|
||||
for (String line : session.getRegionSelector(player.getWorld())
|
||||
.getInformationLines()) {
|
||||
player.print(line);
|
||||
}
|
||||
|
||||
player.print("Size: " + size);
|
||||
player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
|
||||
player.print("# of blocks: " + region.getArea());
|
||||
}
|
||||
|
||||
|
||||
@Command(
|
||||
aliases = { "/count" },
|
||||
usage = "<block>",
|
||||
desc = "Counts the number of a certain type of block",
|
||||
flags = "d",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.analysis.count")
|
||||
public void count(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
|
||||
boolean useData = args.hasFlag('d');
|
||||
if (args.getString(0).contains(":")) {
|
||||
useData = true; //override d flag, if they specified data they want it
|
||||
}
|
||||
int count;
|
||||
if (useData) {
|
||||
Set<BaseBlock> searchBlocks = we.getBlocks(player, args.getString(0), true);
|
||||
count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks);
|
||||
} else {
|
||||
Set<Integer> searchIDs = we.getBlockIDs(player, args.getString(0), true);
|
||||
count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs);
|
||||
}
|
||||
BBC.SELECTION_COUNT.send(player, count);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/distr" },
|
||||
usage = "",
|
||||
desc = "Get the distribution of blocks in the selection",
|
||||
help =
|
||||
"Gets the distribution of blocks in the selection.\n" +
|
||||
"The -c flag gets the distribution of your clipboard.\n" +
|
||||
"The -d flag separates blocks by data",
|
||||
flags = "cd",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.analysis.distr")
|
||||
public void distr(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException, CommandException {
|
||||
|
||||
int size;
|
||||
boolean useData = args.hasFlag('d');
|
||||
List<Countable<Integer>> distribution = null;
|
||||
List<Countable<BaseBlock>> distributionData = null;
|
||||
|
||||
if (args.hasFlag('c')) {
|
||||
// TODO: Update for new clipboard
|
||||
throw new CommandException("Needs to be re-written again");
|
||||
} else {
|
||||
if (useData) {
|
||||
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
|
||||
} else {
|
||||
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()));
|
||||
}
|
||||
size = session.getSelection(player.getWorld()).getArea();
|
||||
}
|
||||
|
||||
if ((useData && distributionData.size() <= 0)
|
||||
|| (!useData && distribution.size() <= 0)) { // *Should* always be false
|
||||
player.printError("No blocks counted.");
|
||||
return;
|
||||
}
|
||||
BBC.SELECTION_DISTR.send(player, size);
|
||||
|
||||
if (useData) {
|
||||
for (Countable<BaseBlock> c : distributionData) {
|
||||
String name = BlockType.fromID(c.getID().getId()).getName();
|
||||
String str = String.format("%-7s (%.3f%%) %s #%d:%d",
|
||||
String.valueOf(c.getAmount()),
|
||||
c.getAmount() / (double) size * 100,
|
||||
name == null ? "Unknown" : name,
|
||||
c.getID().getType(), c.getID().getData());
|
||||
player.print(str);
|
||||
}
|
||||
} else {
|
||||
for (Countable<Integer> c : distribution) {
|
||||
BlockType block = BlockType.fromID(c.getID());
|
||||
String str = String.format("%-7s (%.3f%%) %s #%d",
|
||||
String.valueOf(c.getAmount()),
|
||||
c.getAmount() / (double) size * 100,
|
||||
block == null ? "Unknown" : block.getName(), c.getID());
|
||||
player.print(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/sel", ";", "/desel", "/deselect" },
|
||||
flags = "d",
|
||||
usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]",
|
||||
desc = "Choose a region selector",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
public void select(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
final World world = player.getWorld();
|
||||
if (args.argsLength() == 0) {
|
||||
session.getRegionSelector(world).clear();
|
||||
session.dispatchCUISelection(player);
|
||||
BBC.SELECTION_CLEARED.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
final String typeName = args.getString(0);
|
||||
final RegionSelector oldSelector = session.getRegionSelector(world);
|
||||
|
||||
final RegionSelector selector;
|
||||
if (typeName.equalsIgnoreCase("cuboid")) {
|
||||
selector = new CuboidRegionSelector(oldSelector);
|
||||
player.print("Cuboid: left click for point 1, right click for point 2");
|
||||
} else if (typeName.equalsIgnoreCase("extend")) {
|
||||
selector = new ExtendingCuboidRegionSelector(oldSelector);
|
||||
player.print("Cuboid: left click for a starting point, right click to extend");
|
||||
} else if (typeName.equalsIgnoreCase("poly")) {
|
||||
selector = new Polygonal2DRegionSelector(oldSelector);
|
||||
player.print("2D polygon selector: Left/right click to add a point.");
|
||||
Optional<Integer> limit = ActorSelectorLimits.forActor(player).getPolygonVertexLimit();
|
||||
if (limit.isPresent()) {
|
||||
player.print(limit.get() + " points maximum.");
|
||||
}
|
||||
} else if (typeName.equalsIgnoreCase("ellipsoid")) {
|
||||
selector = new EllipsoidRegionSelector(oldSelector);
|
||||
player.print("Ellipsoid selector: left click=center, right click to extend");
|
||||
} else if (typeName.equalsIgnoreCase("sphere")) {
|
||||
selector = new SphereRegionSelector(oldSelector);
|
||||
player.print("Sphere selector: left click=center, right click to set radius");
|
||||
} else if (typeName.equalsIgnoreCase("cyl")) {
|
||||
selector = new CylinderRegionSelector(oldSelector);
|
||||
player.print("Cylindrical selector: Left click=center, right click to extend.");
|
||||
} else if (typeName.equalsIgnoreCase("convex") || typeName.equalsIgnoreCase("hull") || typeName.equalsIgnoreCase("polyhedron")) {
|
||||
selector = new ConvexPolyhedralRegionSelector(oldSelector);
|
||||
player.print("Convex polyhedral selector: Left click=First vertex, right click to add more.");
|
||||
Optional<Integer> limit = ActorSelectorLimits.forActor(player).getPolyhedronVertexLimit();
|
||||
if (limit.isPresent()) {
|
||||
player.print(limit.get() + " points maximum.");
|
||||
}
|
||||
} else {
|
||||
CommandListBox box = new CommandListBox("Selection modes");
|
||||
StyledFragment contents = box.getContents();
|
||||
StyledFragment tip = contents.createFragment(Style.RED);
|
||||
tip.append("Select one of the modes below:").newLine();
|
||||
|
||||
box.appendCommand("cuboid", "Select two corners of a cuboid");
|
||||
box.appendCommand("extend", "Fast cuboid selection mode");
|
||||
box.appendCommand("poly", "Select a 2D polygon with height");
|
||||
box.appendCommand("ellipsoid", "Select an ellipsoid");
|
||||
box.appendCommand("sphere", "Select a sphere");
|
||||
box.appendCommand("cyl", "Select a cylinder");
|
||||
box.appendCommand("convex", "Select a convex polyhedral");
|
||||
|
||||
player.printRaw(ColorCodeBuilder.asColorCodes(box));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.hasFlag('d')) {
|
||||
RegionSelectorType found = null;
|
||||
for (RegionSelectorType type : RegionSelectorType.values()) {
|
||||
if (type.getSelectorClass() == selector.getClass()) {
|
||||
found = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != null) {
|
||||
session.setDefaultRegionSelector(found);
|
||||
player.print("Your default region selector is now " + found.name() + ".");
|
||||
} else {
|
||||
throw new RuntimeException("Something unexpected happened. Please report this.");
|
||||
}
|
||||
}
|
||||
|
||||
session.setRegionSelector(world, selector);
|
||||
session.dispatchCUISelection(player);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return SelectionCommands.class;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command.composition;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.NullChangeSet;
|
||||
@ -138,15 +139,24 @@ public class SelectionCommand extends SimpleCommand<Operation> {
|
||||
newChunk = fc.copy(true);
|
||||
newChunk.setLoc(queue, value[0], value[1]);
|
||||
} else {
|
||||
newChunk = queue.getChunk(value[0], value[1]);
|
||||
newChunk.fillCuboid(value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data);
|
||||
int bx = value[2] & 15;
|
||||
int tx = value[4] & 15;
|
||||
int bz = value[3] & 15;
|
||||
int tz = value[4] & 15;
|
||||
if (bx == 0 && tx == 15 && bz == 0 && tz == 15) {
|
||||
newChunk = fc.copy(true);
|
||||
newChunk.setLoc(queue, value[0], value[1]);
|
||||
} else {
|
||||
newChunk = queue.getChunk(value[0], value[1]);
|
||||
newChunk.fillCuboid(value[2] & 15, value[4] & 15, minY, maxY, value[3] & 15, value[5] & 15, id, data);
|
||||
}
|
||||
}
|
||||
newChunk.addToQueue();
|
||||
}
|
||||
});
|
||||
queue.enqueue();
|
||||
editSession.setChangeSet(new NullChangeSet());
|
||||
actor.print("[FAWE] Finished queueing " + cuboid.getArea() + " blocks.");
|
||||
BBC.OPERATION.send(actor, BBC.VISITOR_BLOCK.format(cuboid.getArea()));
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
@ -159,9 +169,9 @@ public class SelectionCommand extends SimpleCommand<Operation> {
|
||||
List<String> messages = Lists.newArrayList();
|
||||
operation.addStatusMessages(messages);
|
||||
if (messages.isEmpty()) {
|
||||
actor.print("Operation completed.");
|
||||
BBC.OPERATION.send(actor, 0);
|
||||
} else {
|
||||
actor.print("Operation completed (" + Joiner.on(", ").join(messages) + ").");
|
||||
BBC.OPERATION.send(actor, Joiner.on(", ").join(messages));
|
||||
}
|
||||
|
||||
return operation;
|
||||
|
@ -23,7 +23,6 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
|
||||
public class GravityBrush implements Brush {
|
||||
@ -37,7 +36,6 @@ public class GravityBrush implements Brush {
|
||||
@Override
|
||||
public void build(EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
int size = (int) sizeDouble;
|
||||
BaseBlock air = new BaseBlock(BlockID.AIR, 0);
|
||||
int endY = position.getBlockY() + size;
|
||||
int startPerformY = Math.max(0, position.getBlockY() - size);
|
||||
int startCheckY = fullHeight ? 0 : startPerformY;
|
||||
|
@ -268,7 +268,7 @@ public final class CommandManager {
|
||||
} catch (WrappedCommandException e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
actor.printError(BBC.PREFIX.s() + " " + BBC.WORLDEDIT_CANCEL_REASON.format(faweException.getMessage()));
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
|
||||
} else {
|
||||
Throwable t = e.getCause();
|
||||
actor.printError("Please report this error: [See console]");
|
||||
@ -298,7 +298,7 @@ public final class CommandManager {
|
||||
@Override
|
||||
public void run() {
|
||||
final long time = System.currentTimeMillis() - start;
|
||||
actor.print(BBC.PREFIX.s() + " Action completed in " + (time / 1000d) + " seconds");
|
||||
BBC.ACTION_COMPLETE.send(actor, (time / 1000d));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -409,7 +409,7 @@ public class PlatformManager {
|
||||
} catch (Throwable e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
actor.printError(BBC.PREFIX.s() + " " + BBC.WORLDEDIT_CANCEL_REASON.format(faweException.getMessage()));
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(actor, faweException.getMessage());
|
||||
} else {
|
||||
actor.printError("Please report this error: [See console]");
|
||||
actor.printRaw(e.getClass().getName() + ": " + e.getMessage());
|
||||
@ -496,7 +496,7 @@ public class PlatformManager {
|
||||
} catch (Throwable e) {
|
||||
FaweException faweException = FaweException.get(e);
|
||||
if (faweException != null) {
|
||||
player.printError(BBC.PREFIX.s() + " " + BBC.WORLDEDIT_CANCEL_REASON.format(faweException.getMessage()));
|
||||
BBC.WORLDEDIT_CANCEL_REASON.send(player, faweException.getMessage());
|
||||
} else {
|
||||
player.printError("Please report this error: [See console]");
|
||||
player.printRaw(e.getClass().getName() + ": " + e.getMessage());
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -186,6 +187,6 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
|
||||
@Override
|
||||
public void addStatusMessages(final List<String> messages) {
|
||||
messages.add(this.getAffected() + " blocks affected");
|
||||
messages.add(BBC.VISITOR_BLOCK.format(getAffected()));
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.function.EntityFunction;
|
||||
@ -78,7 +79,7 @@ public class EntityVisitor implements Operation {
|
||||
|
||||
@Override
|
||||
public void addStatusMessages(final List<String> messages) {
|
||||
messages.add(this.getAffected() + " blocks affected");
|
||||
messages.add(BBC.VISITOR_ENTITY.format(getAffected()));
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.FlatRegionFunction;
|
||||
@ -77,7 +78,7 @@ public class FlatRegionVisitor implements Operation {
|
||||
|
||||
@Override
|
||||
public void addStatusMessages(final List<String> messages) {
|
||||
messages.add(this.getAffected() + " columns affected");
|
||||
messages.add(BBC.VISITOR_FLAT.format(getAffected()));
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
@ -66,7 +67,7 @@ public class RegionVisitor implements Operation {
|
||||
|
||||
@Override
|
||||
public void addStatusMessages(final List<String> messages) {
|
||||
messages.add(this.getAffected() + " blocks affected");
|
||||
messages.add(BBC.VISITOR_BLOCK.format(getAffected()));
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.regions.selector;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.internal.cui.CUIRegion;
|
||||
import com.sk89q.worldedit.internal.cui.SelectionPointEvent;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Creates a {@code CuboidRegion} from a user's selections.
|
||||
*/
|
||||
public class CuboidRegionSelector extends com.sk89q.worldedit.regions.CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
|
||||
public transient BlockVector position1;
|
||||
public transient BlockVector position2;
|
||||
public transient CuboidRegion region;
|
||||
|
||||
/**
|
||||
* Create a new region selector with a {@code null} world.
|
||||
*/
|
||||
public CuboidRegionSelector() {
|
||||
this((World) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new region selector.
|
||||
*
|
||||
* @param world the world, which may be {@code null}
|
||||
*/
|
||||
public CuboidRegionSelector(@Nullable World world) {
|
||||
region = new CuboidRegion(world, new Vector(), new Vector());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of another selector.
|
||||
*
|
||||
* @param oldSelector another selector
|
||||
*/
|
||||
public CuboidRegionSelector(RegionSelector oldSelector) {
|
||||
this(checkNotNull(oldSelector).getIncompleteRegion().getWorld());
|
||||
|
||||
if (oldSelector instanceof CuboidRegionSelector) {
|
||||
final CuboidRegionSelector cuboidRegionSelector = (CuboidRegionSelector) oldSelector;
|
||||
|
||||
position1 = cuboidRegionSelector.position1;
|
||||
position2 = cuboidRegionSelector.position2;
|
||||
} else {
|
||||
final Region oldRegion;
|
||||
try {
|
||||
oldRegion = oldSelector.getRegion();
|
||||
} catch (IncompleteRegionException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
position1 = oldRegion.getMinimumPoint().toBlockVector();
|
||||
position2 = oldRegion.getMaximumPoint().toBlockVector();
|
||||
}
|
||||
|
||||
region.setPos1(position1);
|
||||
region.setPos2(position2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new region selector with the given two positions.
|
||||
*
|
||||
* @param world the world
|
||||
* @param position1 position 1
|
||||
* @param position2 position 2
|
||||
*/
|
||||
public CuboidRegionSelector(@Nullable World world, Vector position1, Vector position2) {
|
||||
this(world);
|
||||
checkNotNull(position1);
|
||||
checkNotNull(position2);
|
||||
this.position1 = position1.toBlockVector();
|
||||
this.position2 = position2.toBlockVector();
|
||||
region.setPos1(position1);
|
||||
region.setPos2(position2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return region.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorld(@Nullable World world) {
|
||||
region.setWorld(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectPrimary(Vector position, SelectorLimits limits) {
|
||||
checkNotNull(position);
|
||||
|
||||
if (position1 != null && (position.compareTo(position1) == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
position1 = position.toBlockVector();
|
||||
region.setPos1(position1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectSecondary(Vector position, SelectorLimits limits) {
|
||||
checkNotNull(position);
|
||||
|
||||
if (position2 != null && (position.compareTo(position2)) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
position2 = position.toBlockVector();
|
||||
region.setPos2(position2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
|
||||
checkNotNull(player);
|
||||
checkNotNull(session);
|
||||
checkNotNull(pos);
|
||||
|
||||
if (position1 != null && position2 != null) {
|
||||
BBC.SELECTOR_CUBOID_POS1.send(player, position1, "(" + region.getArea() + ")");
|
||||
} else {
|
||||
BBC.SELECTOR_CUBOID_POS1.send(player, position1, "");
|
||||
}
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getArea()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
|
||||
checkNotNull(player);
|
||||
checkNotNull(session);
|
||||
checkNotNull(pos);
|
||||
|
||||
if (position1 != null && position2 != null) {
|
||||
BBC.SELECTOR_CUBOID_POS2.send(player, position1, "(" + region.getArea() + ")");
|
||||
} else {
|
||||
BBC.SELECTOR_CUBOID_POS2.send(player, position1, "");
|
||||
}
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos, getArea()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explainRegionAdjust(Actor player, LocalSession session) {
|
||||
checkNotNull(player);
|
||||
checkNotNull(session);
|
||||
|
||||
if (position1 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
|
||||
}
|
||||
|
||||
if (position2 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
|
||||
if (position1 == null) {
|
||||
throw new IncompleteRegionException();
|
||||
}
|
||||
|
||||
return position1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefined() {
|
||||
return position1 != null && position2 != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CuboidRegion getRegion() throws IncompleteRegionException {
|
||||
if (position1 == null || position2 == null) {
|
||||
throw new IncompleteRegionException();
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CuboidRegion getIncompleteRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void learnChanges() {
|
||||
position1 = region.getPos1().toBlockVector();
|
||||
position2 = region.getPos2().toBlockVector();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
position1 = null;
|
||||
position2 = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "cuboid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInformationLines() {
|
||||
final List<String> lines = new ArrayList<String>();
|
||||
|
||||
if (position1 != null) {
|
||||
lines.add("Position 1: " + position1);
|
||||
}
|
||||
|
||||
if (position2 != null) {
|
||||
lines.add("Position 2: " + position2);
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
if (position1 == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (position2 == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return region.getArea();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeCUI(LocalSession session, Actor player) {
|
||||
if (position1 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
|
||||
}
|
||||
|
||||
if (position2 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeLegacyCUI(LocalSession session, Actor player) {
|
||||
describeCUI(session, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeID() {
|
||||
return "cuboid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLegacyTypeID() {
|
||||
return "cuboid";
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return CuboidRegionSelector.class;
|
||||
}
|
||||
}
|
@ -96,7 +96,7 @@ public class FaweSponge implements IFawe {
|
||||
|
||||
@Override
|
||||
public void setupVault() {
|
||||
debug(BBC.PREFIX.s() + "Permission hook not implemented yet!");
|
||||
debug("Permission hook not implemented yet!");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user