From 395b46c842c4fef9f682815310125e88fcd20847 Mon Sep 17 00:00:00 2001
From: Jesse Boyd
Date: Tue, 26 Dec 2017 22:15:24 +1100
Subject: [PATCH] Various major
New building mode (using CFI):
- CFI world is generated around the player in realtime
- Use WorldEdit/VS brushes while editing
- This is still being optimized
- Use a 1K radius height brush with near instant results
- https://github.com/boy0001/FastAsyncWorldedit/wiki/CreateFromImage
Early example: https://www.youtube.com/watch?v=jp1SjanWN70
---
.../com/boydti/fawe/bukkit/FaweBukkit.java | 13 +-
.../BukkitImageListener.java | 35 +-
.../bukkit/listener/CFIPacketListener.java | 329 +++
.../bukkit/util/image/BukkitImageViewer.java | 43 +-
.../fawe/bukkit/v0/BukkitChunk_All.java | 5 +-
.../boydti/fawe/bukkit/v0/BukkitQueue_0.java | 101 +
.../fawe/bukkit/v0/BukkitQueue_All.java | 31 +-
.../fawe/bukkit/v1_12/BukkitQueue_1_12.java | 39 +
.../bukkit/v1_12/packet/FaweChunkPacket.java | 95 +-
.../bukkit/v1_12/packet/MCAChunkPacket.java | 83 +
.../fawe/bukkit/v1_7/BukkitQueue17.java | 4 +-
.../fawe/bukkit/wrapper/AsyncWorld.java | 2 +-
bukkit/src/main/resources/plugin.yml | 1 +
.../com/boydti/fawe/command/CFICommand.java | 17 +-
.../com/boydti/fawe/command/CFICommands.java | 85 +-
.../java/com/boydti/fawe/command/Cancel.java | 3 +-
.../java/com/boydti/fawe/config/Settings.java | 8 +-
.../boydti/fawe/example/MappedFaweQueue.java | 165 +-
.../fawe/example/SimpleCharFaweChunk.java | 40 +
.../fawe/jnbt/anvil/HeightMapMCADrawer.java | 15 +-
.../jnbt/anvil/HeightMapMCAGenerator.java | 1779 ++++++++++++-----
.../com/boydti/fawe/jnbt/anvil/MCAQueue.java | 10 +-
.../fawe/object/ChangeSetFaweQueue.java | 2 +-
.../com/boydti/fawe/object/FaweChunk.java | 10 +-
.../boydti/fawe/object/FaweInputStream.java | 22 +
.../boydti/fawe/object/FaweOutputStream.java | 23 +
.../com/boydti/fawe/object/FawePlayer.java | 65 +-
.../com/boydti/fawe/object/FaweQueue.java | 331 ++-
.../boydti/fawe/object/MaskedFaweQueue.java | 2 +-
.../com/boydti/fawe/object/Metadatable.java | 4 +
.../boydti/fawe/object/brush/HeightBrush.java | 81 +-
.../object/brush/heightmap/HeightMap.java | 6 +-
.../brush/heightmap/ScalableHeightMap.java | 2 +-
.../boydti/fawe/object/change/CFIChange.java | 60 +
.../fawe/object/change/StreamChange.java | 51 +
.../fawe/object/changeset/CFIChangeSet.java | 81 +
.../fawe/object/changeset/FaweChangeSet.java | 1 -
.../clipboard/MultiClipboardHolder.java | 2 +-
.../object/collection/DifferentialArray.java | 237 +++
.../collection/DifferentialBlockBuffer.java | 212 ++
.../collection/DifferentialCollection.java | 7 +
.../collection/IterableThreadLocal.java | 6 +-
.../object/extent/FastWorldEditExtent.java | 5 +
.../fawe/object/io/serialize/Serialize.java | 12 +
.../fawe/object/io/serialize/Serializer.java | 50 +
.../fawe/object/mask/MaskedTargetBlock.java | 9 +-
.../fawe/object/queue/DelegateFaweQueue.java | 25 +
.../object/queue/FaweQueueDelegateExtent.java | 1 -
.../fawe/object/queue/IDelegateFaweQueue.java | 515 +++++
.../fawe/object/queue/LazyFaweChunk.java | 219 ++
.../boydti/fawe/util/CleanTextureUtil.java | 4 +-
.../boydti/fawe/util/DelegateFaweQueue.java | 465 -----
.../boydti/fawe/util/EditSessionBuilder.java | 2 +-
.../java/com/boydti/fawe/util/MainUtil.java | 12 +-
.../java/com/boydti/fawe/util/MathMan.java | 4 +
.../com/boydti/fawe/util/ReflectionUtils.java | 7 +-
.../java/com/boydti/fawe/util/SetQueue.java | 3 +
.../com/boydti/fawe/util/image/Drawable.java | 7 +
.../boydti/fawe/util/image/ImageViewer.java | 3 +-
.../boydti/fawe/wrappers/PlayerWrapper.java | 6 +-
.../java/com/sk89q/worldedit/EditSession.java | 87 +-
.../com/sk89q/worldedit/LocalSession.java | 26 +-
.../worldedit/command/BrushCommands.java | 9 +-
.../worldedit/command/BrushProcessor.java | 8 +-
.../worldedit/command/ClipboardCommands.java | 3 -
.../worldedit/command/RegionCommands.java | 7 +-
.../extension/platform/PlatformManager.java | 21 +-
.../extension/platform/PlayerProxy.java | 12 +-
.../extent/AbstractDelegateExtent.java | 18 +-
.../com/sk89q/worldedit/extent/Extent.java | 17 +-
.../internal/command/WorldEditBinding.java | 5 +-
.../worldedit/math/convolution/HeightMap.java | 50 +-
.../com/sk89q/worldedit/util/TargetBlock.java | 214 ++
.../sk89q/worldedit/world/SimpleWorld.java | 186 ++
.../com/thevoxelbox/voxelsniper/Sniper.java | 3 +-
75 files changed, 4771 insertions(+), 1352 deletions(-)
rename bukkit/src/main/java/com/boydti/fawe/bukkit/{util/image => listener}/BukkitImageListener.java (92%)
create mode 100644 bukkit/src/main/java/com/boydti/fawe/bukkit/listener/CFIPacketListener.java
create mode 100644 bukkit/src/main/java/com/boydti/fawe/bukkit/v1_12/packet/MCAChunkPacket.java
create mode 100644 core/src/main/java/com/boydti/fawe/example/SimpleCharFaweChunk.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/change/CFIChange.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/change/StreamChange.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/changeset/CFIChangeSet.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/collection/DifferentialArray.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/collection/DifferentialBlockBuffer.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/collection/DifferentialCollection.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/io/serialize/Serialize.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/io/serialize/Serializer.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/queue/DelegateFaweQueue.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/queue/IDelegateFaweQueue.java
create mode 100644 core/src/main/java/com/boydti/fawe/object/queue/LazyFaweChunk.java
delete mode 100644 core/src/main/java/com/boydti/fawe/util/DelegateFaweQueue.java
create mode 100644 core/src/main/java/com/boydti/fawe/util/image/Drawable.java
create mode 100644 core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
create mode 100644 core/src/main/java/com/sk89q/worldedit/world/SimpleWorld.java
diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
index 4bea196fe6..66c991d325 100644
--- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
+++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java
@@ -4,6 +4,7 @@
import com.boydti.fawe.IFawe;
import com.boydti.fawe.bukkit.chat.BukkitChatManager;
import com.boydti.fawe.bukkit.listener.BrushListener;
+import com.boydti.fawe.bukkit.listener.CFIPacketListener;
import com.boydti.fawe.bukkit.listener.RenderListener;
import com.boydti.fawe.bukkit.regions.FactionsFeature;
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
@@ -19,7 +20,7 @@
import com.boydti.fawe.bukkit.util.VaultUtil;
import com.boydti.fawe.bukkit.util.cui.CUIListener;
import com.boydti.fawe.bukkit.util.cui.StructureCUI;
-import com.boydti.fawe.bukkit.util.image.BukkitImageListener;
+import com.boydti.fawe.bukkit.listener.BukkitImageListener;
import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
@@ -80,6 +81,7 @@ public class FaweBukkit implements IFawe, Listener {
private boolean listeningImages;
private BukkitImageListener imageListener;
+ private CFIPacketListener packetListener;
private boolean listeningCui;
private CUIListener cuiListener;
@@ -136,10 +138,15 @@ public FaweBukkit(BukkitMain plugin) {
MainUtil.handleError(e);
Bukkit.getServer().shutdown();
}
+
+ // Registered delayed Event Listeners
TaskManager.IMP.task(new Runnable() {
@Override
public void run() {
+ // This class
Bukkit.getPluginManager().registerEvents(FaweBukkit.this, FaweBukkit.this.plugin);
+
+ // The tick limiter
new ChunkListener();
}
});
@@ -169,6 +176,10 @@ public synchronized ImageViewer getImageViewer(FawePlayer fp) {
try {
listeningImages = true;
PluginManager manager = Bukkit.getPluginManager();
+ if (manager.getPlugin("ProtocolLib") != null) {
+ packetListener = new CFIPacketListener(plugin);
+ }
+
if (manager.getPlugin("PacketListenerApi") == null) {
File output = new File(plugin.getDataFolder().getParentFile(), "PacketListenerAPI_v3.6.0-SNAPSHOT.jar");
byte[] jarData = Jars.PL_v3_6_0.download();
diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/util/image/BukkitImageListener.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/listener/BukkitImageListener.java
similarity index 92%
rename from bukkit/src/main/java/com/boydti/fawe/bukkit/util/image/BukkitImageListener.java
rename to bukkit/src/main/java/com/boydti/fawe/bukkit/listener/BukkitImageListener.java
index caacf90027..2454a50e5e 100644
--- a/bukkit/src/main/java/com/boydti/fawe/bukkit/util/image/BukkitImageListener.java
+++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/listener/BukkitImageListener.java
@@ -1,5 +1,6 @@
-package com.boydti.fawe.bukkit.util.image;
+package com.boydti.fawe.bukkit.listener;
+import com.boydti.fawe.bukkit.util.image.BukkitImageViewer;
import com.boydti.fawe.command.CFICommands;
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
import com.boydti.fawe.object.FawePlayer;
@@ -60,17 +61,21 @@ public void onPlayerInteractEntity(AsyncPlayerChatEvent event) {
Iterator iter = recipients.iterator();
while (iter.hasNext()) {
Player player = iter.next();
+ if (player.equals(event.getPlayer())) continue;
+
FawePlayer
*/
-public class EditSession extends AbstractWorld implements HasFaweQueue, LightingExtent {
+public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, SimpleWorld {
/**
* Used by {@link #setBlock(Vector, BaseBlock, Stage)} to
* determine which {@link Extent}s should be bypassed.
@@ -181,6 +180,7 @@ public enum Stage {
private String worldName;
private FaweQueue queue;
private boolean wrapped;
+ private boolean fastMode;
private AbstractDelegateExtent extent;
private HistoryExtent history;
private AbstractDelegateExtent bypassHistory;
@@ -214,9 +214,10 @@ public EditSession(@Nonnull World world, @Nullable FaweQueue queue, @Nullable Fa
}
public EditSession(@Nullable String worldName, @Nullable World world, @Nullable FaweQueue queue, @Nullable FawePlayer player, @Nullable FaweLimit limit, @Nullable FaweChangeSet changeSet, @Nullable RegionWrapper[] allowedRegions, @Nullable Boolean autoQueue, @Nullable Boolean fastmode, @Nullable Boolean checkMemory, @Nullable Boolean combineStages, @Nullable BlockBag blockBag, @Nullable EventBus bus, @Nullable EditSessionEvent event) {
+ super(world);
this.worldName = worldName == null ? world == null ? queue == null ? "" : queue.getWorldName() : Fawe.imp().getWorldName(world) : worldName;
if (world == null && this.worldName != null) world = FaweAPI.getWorld(this.worldName);
- this.world = world = WorldWrapper.wrap((AbstractWorld) world);
+ this.world = world = WorldWrapper.wrap(world);
if (bus == null) {
bus = WorldEdit.getInstance().getEventBus();
}
@@ -235,11 +236,6 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
limit = player.getLimit();
}
}
- if (allowedRegions == null) {
- if (player != null && !player.hasWorldEditBypass()) {
- allowedRegions = player.getCurrentRegions();
- }
- }
if (autoQueue == null) {
autoQueue = true;
}
@@ -250,8 +246,9 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
fastmode = player.getSession().hasFastMode();
}
}
+ this.fastMode = fastmode;
if (checkMemory == null) {
- checkMemory = player != null && !fastmode;
+ checkMemory = player != null && !this.fastMode;
}
if (checkMemory) {
if (MemUtil.isMemoryLimitedSlow()) {
@@ -264,21 +261,30 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
this.originalLimit = limit;
this.blockBag = limit.INVENTORY_MODE != 0 ? blockBag : null;
this.limit = limit.copy();
+
if (queue == null) {
- if (world instanceof MCAWorld) {
- queue = ((MCAWorld) world).getQueue();
+ boolean placeChunks = this.fastMode || this.limit.FAST_PLACEMENT;
+ World unwrapped = WorldWrapper.unwrap(world);
+ if (unwrapped instanceof FaweQueue) {
+ queue = (FaweQueue) unwrapped;
+ } else if (unwrapped instanceof MCAWorld) {
+ queue = ((MCAWorld) unwrapped).getQueue();
+ } else if (player != null && world.equals(player.getWorld())) {
+ queue = player.getFaweQueue(placeChunks, autoQueue);
} else {
- queue = SetQueue.IMP.getNewQueue(this, fastmode || this.limit.FAST_PLACEMENT, autoQueue);
+ queue = SetQueue.IMP.getNewQueue(world, placeChunks, autoQueue);
}
}
if (combineStages == null) {
- combineStages = Settings.IMP.HISTORY.COMBINE_STAGES && !(queue instanceof MCAQueue);
- }
- if (!this.limit.FAST_PLACEMENT || !queue.supportsChangeTask()) {
- combineStages = false;
- }
- if (this.blockBag != null) {
- combineStages = false;
+ combineStages =
+ // If it's enabled in the settings
+ Settings.IMP.HISTORY.COMBINE_STAGES
+ // If fast placement is disabled, it's slower to perform a copy on each chunk
+ && this.limit.FAST_PLACEMENT
+ // If the specific queue doesn't support it
+ && queue.supports(FaweQueue.Capability.CHANGE_TASKS)
+ // If the edit uses items from the inventory we can't use a delayed task
+ && this.blockBag == null;
}
if (Settings.IMP.EXPERIMENTAL.ANVIL_QUEUE_MODE && !(queue instanceof MCAQueue)) {
queue = new MCAQueue(queue);
@@ -298,7 +304,7 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
}
this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), bus, event, Stage.BEFORE_CHANGE);
this.bypassHistory = (this.extent = wrapExtent(bypassAll, bus, event, Stage.BEFORE_REORDER));
- if (!fastmode || changeSet != null) {
+ if (!this.fastMode || changeSet != null) {
if (changeSet == null) {
if (Settings.IMP.HISTORY.USE_DISK) {
UUID uuid = player == null ? CONSOLE : player.getUUID();
@@ -337,6 +343,11 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
}
}
}
+ if (allowedRegions == null) {
+ if (player != null && !player.hasWorldEditBypass() && !(queue instanceof HeightMapMCAGenerator)) {
+ allowedRegions = player.getCurrentRegions();
+ }
+ }
this.maxY = getWorld() == null ? 255 : world.getMaxY();
if (allowedRegions != null) {
if (allowedRegions.length == 0) {
@@ -354,6 +365,7 @@ public EditSession(@Nullable String worldName, @Nullable World world, @Nullable
this.extent = new HeightBoundExtent(this.extent, this.limit, 0, maxY);
}
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
+ setExtent(this.extent);
}
/**
@@ -603,13 +615,23 @@ public WorldData getWorldData() {
* @return the change set
*/
public ChangeSet getChangeSet() {
- return history != null ? history.getChangeSet() : changeTask;
+ return changeTask != null ? changeTask : history != null ? history.getChangeSet() : null;
}
public FaweChangeSet getChangeTask() {
return changeTask;
}
+ /**
+ * Set the ChangeSet without hooking into any recording mechanism or triggering any actions.
+ * Used internally to set the ChangeSet during completion to record custom changes which aren't normally recorded
+ * @param set
+ */
+ public void setRawChangeSet(@Nullable FaweChangeSet set) {
+ changeTask = set;
+ changes++;
+ }
+
/**
* Change the ChangeSet being used for this EditSession
* - If history is disabled, no changeset can be set
@@ -819,6 +841,7 @@ public SurvivalModeExtent getSurvivalExtent() {
* @param enabled true to enable
*/
public void setFastMode(final boolean enabled) {
+ this.fastMode = enabled;
disableHistory(enabled);
}
@@ -1150,6 +1173,17 @@ public boolean smartSetBlock(final Vector position, final BaseBlock block) {
}
}
+ @Override
+ public boolean setBlock(Vector position, BaseBlock block) throws MaxChangedBlocksException {
+ try {
+ return setBlock(position, block, Stage.BEFORE_HISTORY);
+ } catch (MaxChangedBlocksException e) {
+ throw e;
+ } catch (WorldEditException e) {
+ throw new RuntimeException("Unexpected exception", e);
+ }
+ }
+
public boolean setBlock(int x, int y, int z, BaseBlock block) {
this.changes++;
try {
@@ -1367,13 +1401,6 @@ public void flushQueue() {
}
}
- @Override
- public
- @Nullable
- Operation commit() {
- return null;
- }
-
/**
* Count the number of blocks of a given list of types in a region.
*
diff --git a/core/src/main/java/com/sk89q/worldedit/LocalSession.java b/core/src/main/java/com/sk89q/worldedit/LocalSession.java
index a543038a65..e9150a5158 100644
--- a/core/src/main/java/com/sk89q/worldedit/LocalSession.java
+++ b/core/src/main/java/com/sk89q/worldedit/LocalSession.java
@@ -190,6 +190,7 @@ public boolean loadSessionHistoryFromDisk(UUID uuid, World world) {
if (Settings.IMP.HISTORY.USE_DISK) {
MAX_HISTORY_SIZE = Integer.MAX_VALUE;
}
+ world = WorldWrapper.unwrap(world);
if (!world.equals(currentWorld)) {
this.uuid = uuid;
// Save history
@@ -354,6 +355,7 @@ public void clearHistory() {
history.clear();
historyNegativeIndex = 0;
historySize = 0;
+ currentWorld = null;
}
/**
@@ -440,7 +442,7 @@ public synchronized void remember(final EditSession editSession, final boolean a
return;
}
// Don't store anything if no changes were made
- if (editSession.size() == 0 || editSession.hasFastMode()) {
+ if (editSession.size() == 0) {
return;
}
FaweChangeSet changeSet = (FaweChangeSet) editSession.getChangeSet();
@@ -510,10 +512,10 @@ public EditSession undo(@Nullable BlockBag newBlockBag, LocalPlayer player) {
*/
public EditSession undo(@Nullable BlockBag newBlockBag, Player player) {
checkNotNull(player);
- loadSessionHistoryFromDisk(player.getUniqueId(), player.getWorld());
+ FawePlayer fp = FawePlayer.wrap(player);
+ loadSessionHistoryFromDisk(player.getUniqueId(), fp.getWorldForEditing());
if (getHistoryNegativeIndex() < history.size()) {
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
- final FawePlayer fp = FawePlayer.wrap(player);
EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
.allowedRegionsEverywhere()
.checkMemory(false)
@@ -557,12 +559,12 @@ public EditSession redo(@Nullable BlockBag newBlockBag, LocalPlayer player) {
*/
public EditSession redo(@Nullable BlockBag newBlockBag, Player player) {
checkNotNull(player);
- loadSessionHistoryFromDisk(player.getUniqueId(), player.getWorld());
+ FawePlayer fp = FawePlayer.wrap(player);
+ loadSessionHistoryFromDisk(player.getUniqueId(), fp.getWorldForEditing());
if (getHistoryNegativeIndex() > 0) {
setDirty();
historyNegativeIndex--;
FaweChangeSet changeSet = getChangeSet(history.get(getHistoryIndex()));
- final FawePlayer fp = FawePlayer.wrap(player);
EditSession newEditSession = new EditSessionBuilder(changeSet.getWorld())
.allowedRegionsEverywhere()
.checkMemory(false)
@@ -1288,11 +1290,15 @@ public EditSession createEditSession(Player player) {
BlockBag blockBag = getBlockBag(player);
- // Create an edit session
- EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
- .getEditSession(player.isPlayer() ? player.getWorld() : null,
- getBlockChangeLimit(), blockBag, player);
- editSession.setFastMode(fastMode);
+ World world = player.getWorld();
+ boolean isPlayer = player.isPlayer();
+ EditSessionBuilder builder = new EditSessionBuilder(world);
+ if (player.isPlayer()) builder.player(FawePlayer.wrap(player));
+ builder.blockBag(blockBag);
+ builder.fastmode(fastMode);
+
+ EditSession editSession = builder.build();
+
Request.request().setEditSession(editSession);
if (mask != null) {
editSession.setMask(mask);
diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
index b4012c93cc..a15c55d71f 100644
--- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
+++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java
@@ -474,10 +474,17 @@ public BrushSettings scatterSchemBrush(Player player, EditSession editSession, L
try {
MultiClipboardHolder clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), clipboard, true);
if (clipboards == null) {
+ BBC.SCHEMATIC_NOT_FOUND.send(player, clipboard);
return null;
}
+ List holders = clipboards.getHolders();
+ if (holders == null) {
+ BBC.SCHEMATIC_NOT_FOUND.send(player, clipboard);
+ return null;
+ }
+
return get(context)
- .setBrush(new PopulateSchem(mask, clipboards.getHolders(), (int) density, rotate))
+ .setBrush(new PopulateSchem(mask, holders, (int) density, rotate))
.setSize(radius);
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushProcessor.java b/core/src/main/java/com/sk89q/worldedit/command/BrushProcessor.java
index 7e8791fa84..aaca703aa2 100644
--- a/core/src/main/java/com/sk89q/worldedit/command/BrushProcessor.java
+++ b/core/src/main/java/com/sk89q/worldedit/command/BrushProcessor.java
@@ -25,9 +25,11 @@ public BrushSettings process(CommandLocals locals, BrushSettings settings) throw
LocalSession session = worldEdit.getSessionManager().get(actor);
session.setTool(null, (Player) actor);
BrushTool tool = session.getBrushTool((Player) actor);
- tool.setPrimary(settings);
- tool.setSecondary(settings);
- BBC.BRUSH_EQUIPPED.send(actor, ((String) locals.get("arguments")).split(" ")[1]);
+ if (tool != null) {
+ tool.setPrimary(settings);
+ tool.setSecondary(settings);
+ BBC.BRUSH_EQUIPPED.send(actor, ((String) locals.get("arguments")).split(" ")[1]);
+ }
return null;
}
}
\ No newline at end of file
diff --git a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
index d1b97d66ab..9a61938439 100644
--- a/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
+++ b/core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
@@ -437,10 +437,7 @@ public void place(Player player, LocalSession session, final EditSession editSes
@Switch('a') final boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
@Switch('s') boolean selectPasted) throws WorldEditException {
ClipboardHolder holder = session.getClipboard();
- System.out.println(holder);
final Clipboard clipboard = holder.getClipboard();
- System.out.println(clipboard.getDimensions());
- System.out.println(clipboard.getClass());
final Vector origin = clipboard.getOrigin();
final Vector to = atOrigin ? origin : session.getPlacementPosition(player);
diff --git a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
index 89968e7471..32364b9dd0 100644
--- a/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
+++ b/core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
@@ -30,7 +30,6 @@
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.object.visitor.Fast2DIterator;
import com.boydti.fawe.util.MathMan;
-import com.boydti.fawe.util.SetQueue;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
@@ -138,7 +137,7 @@ public void fixlighting(Player player) throws WorldEditException {
public void getlighting(Player player) throws WorldEditException {
FawePlayer fp = FawePlayer.wrap(player);
final FaweLocation loc = fp.getLocation();
- FaweQueue queue = SetQueue.IMP.getNewQueue(loc.world, true, false);
+ FaweQueue queue = fp.getFaweQueue(false);
fp.sendMessage("Light: " + queue.getEmmittedLight(loc.x, loc.y, loc.z) + " | " + queue.getSkyLight(loc.x, loc.y, loc.z));
}
@@ -193,7 +192,7 @@ public void setlighting(Player player, @Selection Region region, @Range(min = 0,
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
- final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getWorld(), true, false);
+ final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) fp.getFaweQueue(false);
for (Vector pt : region) {
queue.setBlockLight((int) pt.getX(), (int) pt.getY(), (int) pt.getZ(), value);
}
@@ -217,7 +216,7 @@ public void setskylighting(Player player, @Selection Region region, @Range(min =
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
- final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getWorld(), true, false);
+ final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) fp.getFaweQueue(false);
for (Vector pt : region) {
queue.setSkyLight((int) pt.getX(), (int) pt.getY(), (int) pt.getZ(), value);
}
diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
index 4a587b5c5a..62e71e0111 100644
--- a/core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
+++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
@@ -53,7 +53,6 @@
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.World;
-import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EnumMap;
@@ -277,24 +276,8 @@ public T createProxyActor(T base) {
if (base instanceof Player) {
Player player = (Player) base;
-
- Player permActor = queryCapability(Capability.PERMISSIONS).matchPlayer(player);
- if (permActor == null) {
- permActor = player;
- }
-
- Player cuiActor = queryCapability(Capability.WORLDEDIT_CUI).matchPlayer(player);
- if (cuiActor == null) {
- cuiActor = player;
- }
- try {
- Class> clazz = Class.forName("com.sk89q.worldedit.extension.platform.PlayerProxy");
- Constructor> constructor = clazz.getDeclaredConstructor(Player.class, Actor.class, Actor.class, World.class);
- constructor.setAccessible(true);
- return (T) constructor.newInstance(player, permActor, cuiActor, getWorldForEditing(player.getWorld()));
- } catch (Throwable e) {
- throw new RuntimeException(e);
- }
+ FawePlayer fp = FawePlayer.wrap(player);
+ return (T) fp.createProxy();
} else {
return base;
}
diff --git a/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
index 4202e428b8..d9e9e9dea1 100644
--- a/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
+++ b/core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java
@@ -8,6 +8,7 @@
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extent.inventory.BlockBag;
+import com.sk89q.worldedit.internal.LocalWorldAdapter;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.Location;
@@ -20,6 +21,7 @@ public class PlayerProxy extends AbstractPlayerActor {
private final Actor permActor;
private final Actor cuiActor;
private final World world;
+ private Vector offset = Vector.ZERO;
public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World world) {
Preconditions.checkNotNull(basePlayer);
@@ -32,6 +34,10 @@ public PlayerProxy(Player basePlayer, Actor permActor, Actor cuiActor, World wor
this.world = world;
}
+ public void setOffset(Vector position) {
+ this.offset = position;
+ }
+
public UUID getUniqueId() {
return this.basePlayer.getUniqueId();
}
@@ -62,11 +68,13 @@ public BaseEntity getState() {
}
public Location getLocation() {
- return this.basePlayer.getLocation();
+ Location loc = this.basePlayer.getLocation();
+ return new Location(loc.getExtent(), loc.toVector().add(offset), loc.getDirection());
}
public WorldVector getPosition() {
- return this.basePlayer.getPosition();
+ WorldVector wv = this.basePlayer.getPosition();
+ return new WorldVector(LocalWorldAdapter.wrap(world), wv.add(offset));
}
public double getPitch() {
diff --git a/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
index 4ef9e8e478..86dc834485 100644
--- a/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
+++ b/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java
@@ -46,6 +46,7 @@
public class AbstractDelegateExtent implements LightingExtent {
private transient final Extent extent;
+ private MutableBlockVector mutable = new MutableBlockVector(0, 0, 0);
/**
* Create a new instance.
@@ -64,6 +65,11 @@ public int getSkyLight(int x, int y, int z) {
return 0;
}
+ @Override
+ public int getMaxY() {
+ return extent.getMaxY();
+ }
+
public int getBlockLight(int x, int y, int z) {
if (extent instanceof LightingExtent) {
return ((LightingExtent) extent).getBlockLight(x, y, z);
@@ -115,8 +121,6 @@ public BaseBlock getBlock(Vector position) {
return extent.getLazyBlock(position);
}
- private MutableBlockVector mutable = new MutableBlockVector(0, 0, 0);
-
@Override
public BaseBlock getLazyBlock(int x, int y, int z) {
mutable.mutX(x);
@@ -188,6 +192,16 @@ public String toString() {
return super.toString() + ":" + extent.toString();
}
+ @Override
+ public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
+ return extent.getNearestSurfaceLayer(x, z, y, minY, maxY);
+ }
+
+ @Override
+ public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
+ return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
+ }
+
@Override
public final
@Nullable
diff --git a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java
index 64287e0379..8e217e7d05 100644
--- a/core/src/main/java/com/sk89q/worldedit/extent/Extent.java
+++ b/core/src/main/java/com/sk89q/worldedit/extent/Extent.java
@@ -66,6 +66,10 @@ default BaseBlock getLazyBlock(int x, int y, int z) {
return getLazyBlock(MutableBlockVector.get(x, y, z));
}
+ default int getMaxY() {
+ return 255;
+ }
+
default public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
int clearanceAbove = maxY - y;
int clearanceBelow = y - minY;
@@ -95,7 +99,12 @@ default public int getNearestSurfaceLayer(int x, int z, int y, int minY, int max
for (int layer = y - clearance - 1; layer >= minY; layer--) {
block = getLazyBlock(x, layer, z);
if (FaweCache.isLiquidOrGas(block.getId()) != state) {
- return ((layer + offset) << 3) - (7 - (state ? block.getData() : data1));
+
+// int blockHeight = (newHeight) >> 3;
+// int layerHeight = (newHeight) & 0x7;
+
+ int data = (state ? block.getData() : data1);
+ return ((layer + offset) << 3) + 0;
}
data1 = block.getData();
}
@@ -171,6 +180,12 @@ default public void spawnResource(Region region, Resource gen, int rarity, int f
}
}
+ default boolean contain(Vector pt) {
+ Vector min = getMinimumPoint();
+ Vector max = getMaximumPoint();
+ return (pt.containedWithin(min, max));
+ }
+
default public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
spawnResource(region, new OreGen(this, mask, material, size, minY, maxY), rarity, frequency);
}
diff --git a/core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java b/core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
index 41f3258859..c990651124 100644
--- a/core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
+++ b/core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit.internal.command;
+import com.boydti.fawe.object.FawePlayer;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
@@ -85,7 +86,7 @@ public WorldEditBinding(WorldEdit worldEdit) {
public Object getSelection(ArgumentStack context, Selection selection) throws IncompleteRegionException, ParameterException {
Player sender = getPlayer(context);
LocalSession session = worldEdit.getSessionManager().get(sender);
- return session.getSelection(sender.getWorld());
+ return session.getSelection(FawePlayer.wrap(sender).getWorldForEditing());
}
/**
@@ -338,4 +339,4 @@ public static Class> inject() {
return WorldEditBinding.class;
}
-}
+}
\ No newline at end of file
diff --git a/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java b/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
index 23f7e83b8f..843f1bec93 100644
--- a/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
+++ b/core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
@@ -84,9 +84,19 @@ public HeightMap(EditSession session, Region region, boolean naturalOnly, boolea
} else {
// Store current heightmap data
data = new int[width * height];
- for (int z = 0; z < height; ++z) {
- for (int x = 0; x < width; ++x) {
- data[z * width + x] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY, naturalOnly);
+ int index = 0;
+ if (naturalOnly) {
+ for (int z = 0; z < height; ++z) {
+ for (int x = 0; x < width; ++x, index++) {
+ data[index] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY, naturalOnly);
+ }
+ }
+ } else {
+ int yTmp = 255;
+ for (int z = 0; z < height; ++z) {
+ for (int x = 0; x < width; ++x, index++) {
+ data[index] = yTmp = session.getNearestSurfaceTerrainBlock(x + minX, z + minZ, yTmp, minY, maxY);
+ }
}
}
}
@@ -125,18 +135,7 @@ public int applyFilter(HeightMapFilter filter, int iterations) throws WorldEditE
return layers ? applyLayers(newData) : apply(newData);
}
-// TODO
-// public int averageFilter(int iterations) throws WorldEditException {
-// Vector min = region.getMinimumPoint();
-// Vector max = region.getMaximumPoint();
-// int shift = layers ? 3 : 0;
-// AverageHeightMapFilter filter = new AverageHeightMapFilter(data, width, height, min.getBlockY() << shift, max.getBlockY() << shift);
-// int[] newData = filter.filter(iterations);
-// return layers ? applyLayers(newData) : apply(newData);
-// }
-
public int applyLayers(int[] data) throws WorldEditException {
- System.out.println("Layers");
checkNotNull(data);
Vector minY = region.getMinimumPoint();
@@ -154,6 +153,28 @@ public int applyLayers(int[] data) throws WorldEditException {
// Apply heightmap
int maxY4 = maxY << 4;
int index = 0;
+
+ if (!session.hasExtraExtents()) {
+ // TODO fast change height
+// int chunkZLen = (height + 15) >> 4;
+// int chunkXLen = (width + 15) >> 4;
+// FaweQueue queue = session.getQueue();
+// if (queue instanceof MappedFaweQueue) {
+// MappedFaweQueue mfq = (MappedFaweQueue) queue;
+// for (int cz = 0; cz < chunkZLen; cz++) {
+// for (int cx = 0; cx < chunkXLen; cx++) {
+// mfq.queueChunkLoad(cx, cz, new RunnableVal() {
+// @Override
+// public void run(Object chunk) {
+// todo
+// }
+// });
+// }
+// }
+// }
+ }
+
+
for (int z = 0; z < height; ++z) {
int zr = z + originZ;
for (int x = 0; x < width; ++x) {
@@ -209,7 +230,6 @@ public int applyLayers(int[] data) throws WorldEditException {
}
}
}
-
return blocksChanged;
}
diff --git a/core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java b/core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
new file mode 100644
index 0000000000..02230de782
--- /dev/null
+++ b/core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
@@ -0,0 +1,214 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.util;
+
+import com.boydti.fawe.wrappers.WorldWrapper;
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.blocks.BlockID;
+import com.sk89q.worldedit.blocks.BlockType;
+import com.sk89q.worldedit.entity.Player;
+import com.sk89q.worldedit.internal.LocalWorldAdapter;
+
+/**
+ * This class uses an inefficient method to figure out what block a player
+ * is looking towards.
+ *
+ * Originally written by toi. It was ported to WorldEdit and trimmed down by
+ * sk89q. Thanks to Raphfrk for optimization of toi's original class.
+ */
+public class TargetBlock {
+
+ private LocalWorld world;
+ private int maxDistance;
+ private double checkDistance, curDistance;
+ private Vector targetPos = new Vector();
+ private Vector targetPosDouble = new Vector();
+ private Vector prevPos = new Vector();
+ private Vector offset = new Vector();
+
+ /**
+ * Constructor requiring a player, uses default values
+ *
+ * @param player player to work with
+ */
+ public TargetBlock(LocalPlayer player) {
+ this.world = LocalWorldAdapter.adapt(player.getWorld());
+ this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
+ 300, 1.65, 0.2);
+ }
+
+ /**
+ * Constructor requiring a player, max distance and a checking distance
+ *
+ * @param player LocalPlayer to work with
+ * @param maxDistance how far it checks for blocks
+ * @param checkDistance how often to check for blocks, the smaller the more precise
+ */
+ public TargetBlock(LocalPlayer player, int maxDistance, double checkDistance) {
+ this((Player) player, maxDistance, checkDistance);
+ }
+
+ /**
+ * Constructor requiring a player, max distance and a checking distance
+ *
+ * @param player LocalPlayer to work with
+ * @param maxDistance how far it checks for blocks
+ * @param checkDistance how often to check for blocks, the smaller the more precise
+ */
+ public TargetBlock(Player player, int maxDistance, double checkDistance) {
+ this.world = LocalWorldAdapter.adapt(player.getWorld());
+ this.setValues(player.getPosition(), player.getYaw(), player.getPitch(), maxDistance, 1.65, checkDistance);
+ }
+
+ /**
+ * Set the values, all constructors uses this function
+ *
+ * @param loc location of the view
+ * @param xRotation the X rotation
+ * @param yRotation the Y rotation
+ * @param maxDistance how far it checks for blocks
+ * @param viewHeight where the view is positioned in y-axis
+ * @param checkDistance how often to check for blocks, the smaller the more precise
+ */
+ private void setValues(Vector loc, double xRotation, double yRotation,
+ int maxDistance, double viewHeight, double checkDistance) {
+ this.maxDistance = maxDistance;
+ this.checkDistance = checkDistance;
+ this.curDistance = 0;
+ xRotation = (xRotation + 90) % 360;
+ yRotation = yRotation * -1;
+
+ double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
+
+ offset = new Vector((h * Math.cos(Math.toRadians(xRotation))),
+ (checkDistance * Math.sin(Math.toRadians(yRotation))),
+ (h * Math.sin(Math.toRadians(xRotation))));
+
+ targetPosDouble = loc.add(0, viewHeight, 0);
+ targetPos = targetPosDouble.toBlockPoint();
+ prevPos = targetPos;
+ }
+
+ /**
+ * Returns any block at the sight. Returns null if out of range or if no
+ * viable target was found. Will try to return the last valid air block it finds.
+ *
+ * @return Block
+ */
+ public BlockWorldVector getAnyTargetBlock() {
+ boolean searchForLastBlock = true;
+ BlockWorldVector lastBlock = null;
+ while (getNextBlock() != null) {
+ if (world.getBlockType(getCurrentBlock()) == BlockID.AIR) {
+ if (searchForLastBlock) {
+ lastBlock = getCurrentBlock();
+ if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) {
+ searchForLastBlock = false;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ BlockWorldVector currentBlock = getCurrentBlock();
+ return (currentBlock != null ? currentBlock : lastBlock);
+ }
+
+ /**
+ * Returns the block at the sight. Returns null if out of range or if no
+ * viable target was found
+ *
+ * @return Block
+ */
+ public BlockWorldVector getTargetBlock() {
+ while (getNextBlock() != null && world.getBlockType(getCurrentBlock()) == 0) ;
+ return getCurrentBlock();
+ }
+
+ /**
+ * Returns the block at the sight. Returns null if out of range or if no
+ * viable target was found
+ *
+ * @return Block
+ */
+ public BlockWorldVector getSolidTargetBlock() {
+ while (getNextBlock() != null && BlockType.canPassThrough(world.getBlock(getCurrentBlock()))) ;
+ return getCurrentBlock();
+ }
+
+ /**
+ * Get next block
+ *
+ * @return next block position
+ */
+ public BlockWorldVector getNextBlock() {
+ prevPos = targetPos;
+ do {
+ curDistance += checkDistance;
+
+ targetPosDouble = offset.add(targetPosDouble.getX(),
+ targetPosDouble.getY(),
+ targetPosDouble.getZ());
+ targetPos = targetPosDouble.toBlockPoint();
+ } while (curDistance <= maxDistance
+ && targetPos.getBlockX() == prevPos.getBlockX()
+ && targetPos.getBlockY() == prevPos.getBlockY()
+ && targetPos.getBlockZ() == prevPos.getBlockZ());
+
+ if (curDistance > maxDistance) {
+ return null;
+ }
+
+ return new BlockWorldVector(world, targetPos);
+ }
+
+ /**
+ * Returns the current block along the line of vision
+ *
+ * @return block position
+ */
+ public BlockWorldVector getCurrentBlock() {
+ if (curDistance > maxDistance) {
+ return null;
+ } else {
+ return new BlockWorldVector(world, targetPos);
+ }
+ }
+
+ /**
+ * Returns the previous block in the aimed path
+ *
+ * @return block position
+ */
+ public BlockWorldVector getPreviousBlock() {
+ return new BlockWorldVector(world, prevPos);
+ }
+
+ public WorldVectorFace getAnyTargetBlockFace() {
+ getAnyTargetBlock();
+ return WorldVectorFace.getWorldVectorFace(world, getCurrentBlock(), getPreviousBlock());
+ }
+
+ public WorldVectorFace getTargetBlockFace() {
+ getAnyTargetBlock();
+ return WorldVectorFace.getWorldVectorFace(world, getCurrentBlock(), getPreviousBlock());
+ }
+
+}
diff --git a/core/src/main/java/com/sk89q/worldedit/world/SimpleWorld.java b/core/src/main/java/com/sk89q/worldedit/world/SimpleWorld.java
new file mode 100644
index 0000000000..2ae715f560
--- /dev/null
+++ b/core/src/main/java/com/sk89q/worldedit/world/SimpleWorld.java
@@ -0,0 +1,186 @@
+package com.sk89q.worldedit.world;
+
+import com.boydti.fawe.util.SetQueue;
+import com.sk89q.worldedit.BlockVector2D;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.MaxChangedBlocksException;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.blocks.BaseItem;
+import com.sk89q.worldedit.blocks.BaseItemStack;
+import com.sk89q.worldedit.blocks.BlockID;
+import com.sk89q.worldedit.blocks.BlockType;
+import com.sk89q.worldedit.extension.platform.Platform;
+import com.sk89q.worldedit.function.mask.BlockMask;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.util.Direction;
+import com.sk89q.worldedit.util.TreeGenerator;
+import javax.annotation.Nullable;
+
+public interface SimpleWorld extends World {
+ @Override
+ default boolean useItem(Vector position, BaseItem item, Direction face) {
+ return false;
+ }
+
+ @Override
+ default boolean setBlockType(Vector position, int type) {
+ try {
+ return setBlock(position, new BaseBlock(type));
+ } catch (WorldEditException ignored) {
+ return false;
+ }
+ }
+
+ @Override
+ default void setBlockData(Vector position, int data) {
+ try {
+ setBlock(position, new BaseBlock(getLazyBlock(position).getType(), data));
+ } catch (WorldEditException ignored) {
+ }
+ }
+
+ @Override
+ default boolean setTypeIdAndData(Vector position, int type, int data) {
+ try {
+ return setBlock(position, new BaseBlock(type, data));
+ } catch (WorldEditException ignored) {
+ return false;
+ }
+ }
+
+ @Override
+ default boolean setBlock(Vector pt, BaseBlock block) throws WorldEditException {
+ return setBlock(pt, block, true);
+ }
+
+ @Override
+ default int getMaxY() {
+ return getMaximumPoint().getBlockY();
+ }
+
+ @Override
+ default boolean isValidBlockType(int type) {
+ return BlockType.fromID(type) != null;
+ }
+
+ @Override
+ default boolean usesBlockData(int type) {
+ // We future proof here by assuming all unknown blocks use data
+ return BlockType.usesData(type) || BlockType.fromID(type) == null;
+ }
+
+ @Override
+ default Mask createLiquidMask() {
+ return new BlockMask(this,
+ new BaseBlock(BlockID.STATIONARY_LAVA, -1),
+ new BaseBlock(BlockID.LAVA, -1),
+ new BaseBlock(BlockID.STATIONARY_WATER, -1),
+ new BaseBlock(BlockID.WATER, -1));
+ }
+
+ @Override
+ default int getBlockType(Vector pt) {
+ return getLazyBlock(pt).getType();
+ }
+
+ @Override
+ default int getBlockData(Vector pt) {
+ return getLazyBlock(pt).getData();
+ }
+
+ @Override
+ default void dropItem(Vector pt, BaseItemStack item, int times) {
+ for (int i = 0; i < times; ++i) {
+ dropItem(pt, item);
+ }
+ }
+
+ @Override
+ default void simulateBlockMine(Vector pt) {
+ BaseBlock block = getLazyBlock(pt);
+ BaseItemStack stack = BlockType.getBlockDrop(block.getId(), (short) block.getData());
+
+ if (stack != null) {
+ final int amount = stack.getAmount();
+ if (amount > 1) {
+ dropItem(pt, new BaseItemStack(stack.getType(), 1, stack.getData()), amount);
+ } else {
+ dropItem(pt, stack, amount);
+ }
+ }
+
+ try {
+ setBlock(pt, new BaseBlock(BlockID.AIR));
+ } catch (WorldEditException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ default boolean generateTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException {
+ return generateTree(TreeGenerator.TreeType.TREE, editSession, pt);
+ }
+
+ @Override
+ default boolean generateBigTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException {
+ return generateTree(TreeGenerator.TreeType.BIG_TREE, editSession, pt);
+ }
+
+ @Override
+ default boolean generateBirchTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException {
+ return generateTree(TreeGenerator.TreeType.BIRCH, editSession, pt);
+ }
+
+ @Override
+ default boolean generateRedwoodTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException {
+ return generateTree(TreeGenerator.TreeType.REDWOOD, editSession, pt);
+ }
+
+ @Override
+ default boolean generateTallRedwoodTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException {
+ return generateTree(TreeGenerator.TreeType.TALL_REDWOOD, editSession, pt);
+ }
+
+ @Override
+ default void checkLoadedChunk(Vector pt) {
+ }
+
+ @Override
+ default void fixAfterFastMode(Iterable chunks) {
+ }
+
+ @Override
+ default void fixLighting(Iterable chunks) {
+ }
+
+ @Override
+ default boolean playEffect(Vector position, int type, int data) {
+ return false;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ default boolean queueBlockBreakEffect(Platform server, Vector position, int blockId, double priority) {
+ SetQueue.IMP.addTask(() -> playEffect(position, 2001, blockId));
+ return true;
+ }
+
+ @Override
+ default Vector getMinimumPoint() {
+ return new Vector(-30000000, 0, -30000000);
+ }
+
+ @Override
+ default Vector getMaximumPoint() {
+ return new Vector(30000000, 255, 30000000);
+ }
+
+ @Override
+ default @Nullable
+ Operation commit() {
+ return null;
+ }
+}
diff --git a/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java b/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java
index 13668def28..642060247a 100644
--- a/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java
+++ b/favs/src/main/java/com/thevoxelbox/voxelsniper/Sniper.java
@@ -1,7 +1,6 @@
package com.thevoxelbox.voxelsniper;
import com.boydti.fawe.Fawe;
-import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
@@ -167,7 +166,7 @@ public synchronized boolean snipeOnCurrentThread(FawePlayer fp, final Action act
Player bukkitPlayer = getPlayer();
World bukkitWorld = bukkitPlayer.getWorld();
- FaweQueue baseQueue = FaweAPI.createQueue(fp.getLocation().world, false);
+ FaweQueue baseQueue = fp.getFaweQueue(false);
RegionWrapper[] mask = WEManager.IMP.getMask(fp);
if (mask.length == 0) {
BBC.NO_REGION.send(fp);