diff --git a/core/src/main/java/com/boydti/fawe/FaweCache.java b/core/src/main/java/com/boydti/fawe/FaweCache.java index 56b84f68..e1b308f7 100644 --- a/core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/core/src/main/java/com/boydti/fawe/FaweCache.java @@ -615,6 +615,8 @@ public class FaweCache { case 33: case 151: case 178: + case 210: + case 211: return true; default: return false; diff --git a/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java new file mode 100644 index 00000000..53a5402c --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/command/AnvilCommands.java @@ -0,0 +1,55 @@ +package com.boydti.fawe.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.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.Patterns; +import com.sk89q.worldedit.internal.annotation.Selection; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.command.parametric.Optional; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.REGION; + +public class AnvilCommands { + + private final WorldEdit worldEdit; + + /** + * Create a new instance. + * + * @param worldEdit reference to WorldEdit + */ + public AnvilCommands(WorldEdit worldEdit) { + checkNotNull(worldEdit); + this.worldEdit = worldEdit; + } + + @Command( + aliases = { "/replaceall", "/rea", "/repall" }, + usage = "[from-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); + } + +} diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/AnvilRegion.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/AnvilRegion.java new file mode 100644 index 00000000..350d295d --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/AnvilRegion.java @@ -0,0 +1,4 @@ +package com.boydti.fawe.jnbt.anvil; + +public class AnvilRegion { +} diff --git a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java index 8ba22621..937e47c7 100644 --- a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java @@ -26,6 +26,7 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class HistoryExtent extends AbstractDelegateExtent { + private final AbstractDelegateExtent extent; private FaweChangeSet changeSet; private final FaweQueue queue; private final EditSession session; @@ -39,6 +40,7 @@ public class HistoryExtent extends AbstractDelegateExtent { public HistoryExtent(final EditSession session, final Extent extent, final FaweChangeSet changeSet, FaweQueue queue) { super(extent); checkNotNull(changeSet); + this.extent = (AbstractDelegateExtent) extent; this.queue = queue; this.changeSet = changeSet; this.session = session; @@ -53,13 +55,10 @@ public class HistoryExtent extends AbstractDelegateExtent { } @Override - public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { - int y = location.getBlockY(); + public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException { if (y > 255 || y < 0) { return false; } - int x = location.getBlockX(); - int z = location.getBlockZ(); int combined = queue.getCombinedId4DataDebug(x, y, z, 0, session); int id = (combined >> 4); if (id == block.getId()) { @@ -80,13 +79,28 @@ public class HistoryExtent extends AbstractDelegateExtent { } else { try { CompoundTag tag = queue.getTileEntity(x, y, z); - this.changeSet.add(location, new BaseBlock(id, combined & 0xF, tag), block); + this.changeSet.add(x, y, z, new BaseBlock(id, combined & 0xF, tag), block); } catch (Throwable e) { e.printStackTrace(); this.changeSet.add(x, y, z, combined, block); } } - return super.setBlock(location, block); + return extent.setBlock(x, y, z, block); + } + + @Override + public BaseBlock getLazyBlock(int x, int y, int z) { + return extent.getLazyBlock(x, y, z); + } + + @Override + public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { + return setBlock((int) location.x, (int) location.y, (int) location.z, block); + } + + @Override + public BaseBlock getLazyBlock(Vector location) { + return getLazyBlock((int) location.x, (int) location.y, (int) location.z); } @Nullable diff --git a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java index 80cc64d8..a0fdc092 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java @@ -1,5 +1,6 @@ package com.boydti.fawe.object.extent; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.ReflectionUtils; @@ -8,7 +9,6 @@ import com.sk89q.jnbt.DoubleTag; import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -63,24 +63,34 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { return super.getBiome(position); } - private BaseBlock lastBlock; - private BlockVector lastVector; + @Override + public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { + return setBlock((int) location.x, (int) location.y, (int) location.z, block); + } @Override - public BaseBlock getLazyBlock(final Vector position) { - if ((this.lastBlock != null) && this.lastVector.equals(position.toBlockVector())) { - return this.lastBlock; + public BaseBlock getLazyBlock(Vector location) { + return getLazyBlock((int) location.x, (int) location.y, (int) location.z); + } + + @Override + public BaseBlock getLazyBlock(int x, int y, int z) { + int combinedId4Data = queue.getCombinedId4Data(x, y, z, 0); + int id = FaweCache.getId(combinedId4Data); + if (!FaweCache.hasNBT(id)) { + return FaweCache.CACHE_BLOCK[combinedId4Data]; } - if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) { - try { - this.lastVector = position.toBlockVector(); - return this.lastBlock = super.getBlock(position); - } catch (final Throwable e) { - return EditSession.nullBlock; + try { + CompoundTag tile = queue.getTileEntity(x, y, z); + if (tile != null) { + return new BaseBlock(id, FaweCache.getData(combinedId4Data), tile); + } else { + return FaweCache.CACHE_BLOCK[combinedId4Data]; } + } catch (Throwable e) { + MainUtil.handleError(e); + return FaweCache.CACHE_BLOCK[combinedId4Data]; } - this.lastVector = position.toBlockVector(); - return this.lastBlock = super.getBlock(position); } @Override @@ -105,8 +115,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { } @Override - public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { - final int y = (int) location.y; + public boolean setBlock(int x, int y, int z, final BaseBlock block) throws WorldEditException { switch (y) { case 0: case 1: @@ -368,8 +377,6 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { default: return false; } - final int x = (int) location.x; - final int z = (int) location.z; final short id = (short) block.getId(); switch (id) { case 63: diff --git a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java index 39a3cdf2..79f17f84 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java @@ -55,6 +55,11 @@ public class NullExtent extends FaweRegionExtent { throw new FaweException(reason); } + @Override + public BaseBlock getLazyBlock(int x, int y, int z) { + throw new FaweException(reason); + } + @Override public Entity createEntity(final Location arg0, final BaseEntity arg1) { throw new FaweException(reason); diff --git a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java index 9cb50fcb..90fafdfe 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java @@ -5,13 +5,14 @@ import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.util.WEManager; -import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; @@ -21,11 +22,13 @@ import java.util.List; public class ProcessedWEExtent extends FaweRegionExtent { private final FaweLimit limit; private final RegionWrapper[] mask; + private final AbstractDelegateExtent extent; public ProcessedWEExtent(final Extent parent, final RegionWrapper[] mask, FaweLimit limit) { super(parent); this.mask = mask; this.limit = limit; + this.extent = (AbstractDelegateExtent) parent; } @Override @@ -50,14 +53,6 @@ public class ProcessedWEExtent extends FaweRegionExtent { return super.getBiome(position); } - private BaseBlock lastBlock; - private BlockVector lastVector; - - @Override - public BaseBlock getLazyBlock(final Vector position) { - return super.getLazyBlock(position); - } - @Override public List getEntities() { return super.getEntities(); @@ -69,28 +64,64 @@ public class ProcessedWEExtent extends FaweRegionExtent { } @Override - public BaseBlock getBlock(final Vector position) { - return this.getLazyBlock(position); + public BaseBlock getLazyBlock(int x, int y, int z) { + if (WEManager.IMP.maskContains(this.mask, x, z)) { + if (!limit.MAX_CHECKS()) { + WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES); + return EditSession.nullBlock; + } else { + return extent.getLazyBlock(x, y, z); + } + } else if (!limit.MAX_FAILS()) { + WEManager.IMP.cancelEditSafe(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + return EditSession.nullBlock; + } else { + return EditSession.nullBlock; + } } @Override public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { + return setBlock((int) location.x, (int) location.y, (int) location.z, block); + } + + @Override + public BaseBlock getLazyBlock(Vector location) { + return getLazyBlock((int) location.x, (int) location.y, (int) location.z); + } + + @Override + public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException { if (block.hasNbtData() && FaweCache.hasNBT(block.getType())) { if (!limit.MAX_BLOCKSTATES()) { WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_TILES); return false; + } else if (WEManager.IMP.maskContains(this.mask, x, z)) { + if (!limit.MAX_CHANGES()) { + WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES); + return false; + } + return extent.setBlock(x, y, z, block); + } else if (!limit.MAX_FAILS()) { + WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + return false; + } else { + return false; } } - if (WEManager.IMP.maskContains(this.mask, (int) location.x, (int) location.z)) { + if (WEManager.IMP.maskContains(this.mask, x, z)) { if (!limit.MAX_CHANGES()) { WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES); return false; + } else { + return extent.setBlock(x, y, z, block); } - return super.setBlock(location, block); } else if (!limit.MAX_FAILS()) { WEManager.IMP.cancelEdit(this, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + return false; + } else { + return false; } - return false; } @Override diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 9df5f5aa..6ee769f1 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -32,7 +32,6 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.object.NullChangeSet; import com.boydti.fawe.object.RegionWrapper; -import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet; import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.FaweChangeSet; @@ -43,13 +42,10 @@ import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.ProcessedWEExtent; import com.boydti.fawe.util.ExtentTraverser; -import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.Perm; import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.wrappers.WorldWrapper; -import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; import com.sk89q.worldedit.blocks.BlockType; @@ -118,7 +114,6 @@ import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -158,10 +153,10 @@ public class EditSession implements Extent { private World world; private FaweQueue queue; - private Extent extent; + private AbstractDelegateExtent extent; private HistoryExtent history; - private Extent bypassHistory; - private Extent bypassAll; + private AbstractDelegateExtent bypassHistory; + private AbstractDelegateExtent bypassAll; private FaweLimit originalLimit; private FaweLimit limit; private FawePlayer player; @@ -170,6 +165,8 @@ public class EditSession implements Extent { private int changes = 0; private BlockBag blockBag; + private Vector mutable = new Vector(); + public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7"); public static final BaseBiome nullBiome = new BaseBiome(0); public static final BaseBlock nullBlock = FaweCache.CACHE_BLOCK[0]; @@ -424,16 +421,20 @@ public class EditSession implements Extent { } @Deprecated - private Extent wrapExtent(final Extent extent, final EventBus eventBus, EditSessionEvent event, final Stage stage) { + private AbstractDelegateExtent wrapExtent(final AbstractDelegateExtent extent, final EventBus eventBus, EditSessionEvent event, final Stage stage) { event = event.clone(stage); event.setExtent(extent); eventBus.post(event); final Extent toReturn = event.getExtent(); + if (!(toReturn instanceof AbstractDelegateExtent)) { + Fawe.debug("Extent " + toReturn + " must be AbstractDelegateExtent"); + return extent; + } if (toReturn != extent) { String className = toReturn.getClass().getName().toLowerCase(); for (String allowed : Settings.EXTENT.ALLOWED_PLUGINS) { if (className.contains(allowed.toLowerCase())) { - return toReturn; + return (AbstractDelegateExtent) toReturn; } } if (Settings.EXTENT.DEBUG) { @@ -614,7 +615,7 @@ public class EditSession implements Extent { if (beforeHistory != null && beforeHistory.exists()) { beforeHistory.setNext(afterHistory.get()); } else { - extent = afterHistory.get(); + extent = (AbstractDelegateExtent) afterHistory.get(); } } } else if (traverseHistory == null || !traverseHistory.exists()) { @@ -690,30 +691,16 @@ public class EditSession implements Extent { @Override public BaseBlock getLazyBlock(final Vector position) { - return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + return getLazyBlock((int) position.x, (int) position.y, (int) position.z); } public BaseBlock getLazyBlock(int x, int y, int z) { - if (!limit.MAX_CHECKS()) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS); - } - int combinedId4Data = queue.getCombinedId4DataDebug(x, y, z, 0, this); - int id = FaweCache.getId(combinedId4Data); - if (!FaweCache.hasNBT(id)) { - return FaweCache.CACHE_BLOCK[combinedId4Data]; - } - try { - CompoundTag tile = queue.getTileEntity(x, y, z); - return new BaseBlock(id, FaweCache.getData(combinedId4Data), tile); - } catch (Throwable e) { - MainUtil.handleError(e); - return FaweCache.CACHE_BLOCK[combinedId4Data]; - } + return extent.getLazyBlock(x, y, z); } @Override public BaseBlock getBlock(final Vector position) { - return this.getLazyBlock(position); + return getLazyBlock((int) position.x, (int) position.y, (int) position.z); } /** @@ -757,7 +744,7 @@ public class EditSession implements Extent { */ @Deprecated public BaseBlock rawGetBlock(final Vector position) { - return this.getLazyBlock(position); + return bypassAll.getLazyBlock(position); } /** @@ -784,7 +771,6 @@ public class EditSession implements Extent { * @return height of highest block found or 'minY' */ public int getHighestTerrainBlock(final int x, final int z, final int minY, final int maxY, final boolean naturalOnly) { - Vector pt = new Vector(x, 0, z); for (int y = maxY; y >= minY; --y) { BaseBlock block = getLazyBlock(x, y, z); final int id = block.getId(); @@ -939,13 +925,20 @@ public class EditSession implements Extent { } } + public boolean setBlock(int x, int y, int z, BaseBlock block) { + this.changes++; + try { + return this.extent.setBlock(x, y, z, block); + } catch (WorldEditException e) { + throw new RuntimeException("Unexpected exception", e); + } + } + @Override public boolean setBlock(final Vector position, final BaseBlock block) throws MaxChangedBlocksException { this.changes++; try { return this.extent.setBlock(position, block); - } catch (final MaxChangedBlocksException e) { - throw e; } catch (final WorldEditException e) { throw new RuntimeException("Unexpected exception", e); } @@ -1658,7 +1651,6 @@ public class EditSession implements Extent { checkNotNull(dir); checkArgument(distance >= 1, "distance >= 1 required"); final Vector displace = dir.multiply(distance); - final Vector mutable = new Vector(0, 0, 0); // Remove the original blocks final com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ? new BlockPattern(replacement) : new BlockPattern(new BaseBlock(BlockID.AIR)); final BlockReplace remove = new BlockReplace(EditSession.this, pattern) { @@ -2030,27 +2022,25 @@ public class EditSession implements Extent { final int ceilRadius = (int) Math.ceil(radius); for (int x = ox - ceilRadius; x <= (ox + ceilRadius); ++x) { + int dx = x - ox; + int dx2 = dx * dx; for (int z = oz - ceilRadius; z <= (oz + ceilRadius); ++z) { - if ((new Vector(x, oy, z)).distanceSq(position) > radiusSq) { + int dz = z - oz; + int dz2 = dz * dz; + if (dx2 + dz2 > radiusSq) { continue; } - for (int y = 255; y >= 1; --y) { - final Vector pt = new Vector(x, y, z); - final int id = this.getBlockType(pt); - + final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z)); switch (id) { case BlockID.ICE: - this.setBlock(pt, water); + this.setBlock(x, y, z, water); break; - case BlockID.SNOW: - this.setBlock(pt, air); + this.setBlock(x, y, z, air); break; - case BlockID.AIR: continue; - default: break; } @@ -2084,22 +2074,22 @@ public class EditSession implements Extent { final int ceilRadius = (int) Math.ceil(radius); for (int x = ox - ceilRadius; x <= (ox + ceilRadius); ++x) { + int dx = x - ox; + int dx2 = dx * dx; for (int z = oz - ceilRadius; z <= (oz + ceilRadius); ++z) { - if ((new Vector(x, oy, z)).distanceSq(position) > radiusSq) { + int dz = z - oz; + int dz2 = dz * dz; + if (dx2 + dz2 > radiusSq) { continue; } - for (int y = 255; y >= 1; --y) { - final Vector pt = new Vector(x, y, z); - final int id = this.getBlockType(pt); - + final int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z)); if (id == BlockID.AIR) { continue; } - // Ice! if ((id == BlockID.WATER) || (id == BlockID.STATIONARY_WATER)) { - this.setBlock(pt, ice); + this.setBlock(x, y, z, ice); break; } @@ -2114,7 +2104,7 @@ public class EditSession implements Extent { } // add snow cover - this.setBlock(pt.add(0, 1, 0), snow); + this.setBlock(x, y + 1, z, snow); break; } } @@ -2158,22 +2148,25 @@ public class EditSession implements Extent { final int ceilRadius = (int) Math.ceil(radius); for (int x = ox - ceilRadius; x <= (ox + ceilRadius); ++x) { + int dx = x - ox; + int dx2 = dx * dx; for (int z = oz - ceilRadius; z <= (oz + ceilRadius); ++z) { - if ((new Vector(x, oy, z)).distanceSq(position) > radiusSq) { + int dz = z - oz; + int dz2 = dz * dz; + if (dx2 + dz2 > radiusSq) { continue; } - loop: for (int y = 255; y >= 1; --y) { - final Vector pt = new Vector(x, y, z); - final int id = this.getBlockType(pt); - final int data = this.getBlockData(pt); + BaseBlock block = getLazyBlock(x, y, z); + final int id = block.getId(); + final int data = block.getData(); switch (id) { case BlockID.DIRT: if (onlyNormalDirt && (data != 0)) { break loop; } - this.setBlock(pt, grass); + this.setBlock(x, y, z, grass); break loop; case BlockID.WATER: @@ -2237,48 +2230,33 @@ public class EditSession implements Extent { * @throws MaxChangedBlocksException thrown if too many blocks are changed */ public int makeForest(final Vector basePosition, final int size, final double density, final TreeGenerator treeGenerator) { - final ArrayDeque trees = new ArrayDeque<>(); - for (int x = basePosition.getBlockX() - size; x <= (basePosition.getBlockX() + size); ++x) { - for (int z = basePosition.getBlockZ() - size; z <= (basePosition.getBlockZ() + size); ++z) { - // Don't want to be in the ground - if (!this.getLazyBlock(x, basePosition.getBlockY(), z).isAir()) { - continue; - } - // The gods don't want a tree here - if (FaweCache.RANDOM.random(65536) >= (density * 65536)) { - continue; - } // def 0.05 - trees.add(new Vector(x, 0, z)); - } - } - if (trees.size() > 0) { - TaskManager.IMP.objectTask(trees, new RunnableVal() { - @Override - public void run(Vector vector) { - try { - for (int y = basePosition.getBlockY(); y >= (basePosition.getBlockY() - 10); --y) { - vector = new Vector(vector.getX(), y, vector.getZ()); - final int t = getBlock(vector).getType(); - if ((t == BlockID.GRASS) || (t == BlockID.DIRT)) { - treeGenerator.generate(EditSession.this, new Vector(vector.getX(), y + 1, vector.getZ())); - break; - } else if (t == BlockID.SNOW) { - setBlock(vector, nullBlock); - } else if (t != BlockID.AIR) { // Trees won't grow on this! - break; - } + try { + for (int x = basePosition.getBlockX() - size; x <= (basePosition.getBlockX() + size); ++x) { + for (int z = basePosition.getBlockZ() - size; z <= (basePosition.getBlockZ() + size); ++z) { + // Don't want to be in the ground + if (!this.getLazyBlock(x, basePosition.getBlockY(), z).isAir()) { + continue; + } + // The gods don't want a tree here + if (FaweCache.RANDOM.random(65536) >= (density * 65536)) { + continue; + } // def 0.05 + this.changes++; + for (int y = basePosition.getBlockY(); y >= (basePosition.getBlockY() - 10); --y) { + final int t = getLazyBlock(x, y, z).getType(); + if ((t == BlockID.GRASS) || (t == BlockID.DIRT)) { + treeGenerator.generate(EditSession.this, new Vector(x, y + 1, z)); + break; + } else if (t == BlockID.SNOW) { + setBlock(x, y, z, nullBlock); + } else if (t != BlockID.AIR) { // Trees won't grow on this! + break; } - } catch (MaxChangedBlocksException ignore) { } } - }, new Runnable() { - @Override - public void run() { - queue.enqueue(); - } - }); - } - return this.changes = trees.size(); + } + } catch (MaxChangedBlocksException ignore) {} + return this.changes; } /** @@ -2306,10 +2284,7 @@ public class EditSession implements Extent { for (int x = minX; x <= maxX; ++x) { for (int y = minY; y <= maxY; ++y) { for (int z = minZ; z <= maxZ; ++z) { - final Vector pt = new Vector(x, y, z); - - final int id = this.getBlockType(pt); - + int id = FaweCache.getId(queue.getCombinedId4Data(x, y, z)); if (map.containsKey(id)) { map.get(id).increment(); } else { @@ -2323,7 +2298,6 @@ public class EditSession implements Extent { } else { for (final Vector pt : region) { final int id = this.getBlockType(pt); - if (map.containsKey(id)) { map.get(id).increment(); } else { @@ -2364,10 +2338,7 @@ public class EditSession implements Extent { for (int x = minX; x <= maxX; ++x) { for (int y = minY; y <= maxY; ++y) { for (int z = minZ; z <= maxZ; ++z) { - final Vector pt = new Vector(x, y, z); - - final BaseBlock blk = FaweCache.getBlock(this.getBlockType(pt), this.getBlockData(pt)); - + final BaseBlock blk = getLazyBlock(x, y, z); if (map.containsKey(blk)) { map.get(blk).increment(); } else { diff --git a/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java new file mode 100644 index 00000000..645cdf74 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java @@ -0,0 +1,152 @@ +/* + * 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.extent; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.function.operation.OperationQueue; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BaseBiome; + +import javax.annotation.Nullable; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A base class for {@link Extent}s that merely passes extents onto another. + */ +public abstract class AbstractDelegateExtent implements Extent { + + private final Extent extent; + + /** + * Create a new instance. + * + * @param extent the extent + */ + protected AbstractDelegateExtent(Extent extent) { + checkNotNull(extent); + this.extent = extent; + } + + /** + * Get the extent. + * + * @return the extent + */ + public Extent getExtent() { + return extent; + } + + @Override + public BaseBlock getBlock(Vector position) { + return extent.getLazyBlock(position); + } + + private Vector mutable = new Vector(0,0,0); + + public BaseBlock getLazyBlock(int x, int y, int z) { + mutable.x = x; + mutable.y = y; + mutable.z = z; + return extent.getLazyBlock(mutable); + } + + @Override + public BaseBlock getLazyBlock(Vector position) { + return extent.getLazyBlock(position); + } + + public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException { + mutable.x = x; + mutable.y = y; + mutable.z = z; + return extent.setBlock(mutable, block); + } + + @Override + public boolean setBlock(Vector location, BaseBlock block) throws WorldEditException { + return extent.setBlock(location, block); + } + + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity) { + return extent.createEntity(location, entity); + } + + @Override + public List getEntities() { + return extent.getEntities(); + } + + @Override + public List getEntities(Region region) { + return extent.getEntities(region); + } + + @Override + public BaseBiome getBiome(Vector2D position) { + return extent.getBiome(position); + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + return extent.setBiome(position, biome); + } + + @Override + public Vector getMinimumPoint() { + return extent.getMinimumPoint(); + } + + @Override + public Vector getMaximumPoint() { + return extent.getMaximumPoint(); + } + + protected Operation commitBefore() { + return null; + } + + @Override + public final @Nullable Operation commit() { + Operation ours = commitBefore(); + Operation other = extent.commit(); + if (ours != null && other != null) { + return new OperationQueue(ours, other); + } else if (ours != null) { + return ours; + } else if (other != null) { + return other; + } else { + return null; + } + } + +}