Feature/propagate diff and object cleanup (#1190)

* Feature/main/propagate diff annotations (#1187)

* 25% done

* More work

* More work

* 50%

* More work

* 75%

* 100% & cleanup

* Update adapters

* Squish squash, applesauce

commit 275ba9bd84
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Sat Jul 17 01:10:20 2021 +0200

    Update dependency com.comphenix.protocol:ProtocolLib to v4.7.0 (#1173)

    Co-authored-by: Renovate Bot <bot@renovateapp.com>

commit 9fd8984804
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Sat Jul 17 01:09:29 2021 +0200

    Update dependency org.checkerframework:checker-qual to v3.16.0 (#1184)

    Co-authored-by: Renovate Bot <bot@renovateapp.com>

commit 861fb45e5c
Author: dordsor21 <dordsor21@gmail.com>
Date:   Fri Jul 16 19:07:02 2021 +0100

    Fix #1075

commit 420c45a29a
Author: dordsor21 <dordsor21@gmail.com>
Date:   Fri Jul 16 18:48:21 2021 +0100

    Entity removal should be on the main thread as we're just passing through rather than doing chunk operations
     - Fixes #1164
     - Not working: butcher/remove history

commit 4d4db7dcd0
Author: SirYwell <hannesgreule@outlook.de>
Date:   Fri Jul 16 17:52:44 2021 +0200

    Make sure leaves category is loaded for heightmaps (fixes #1176)

commit c98f6e4f37
Author: dordsor21 <dordsor21@gmail.com>
Date:   Fri Jul 16 10:44:52 2021 +0100

    Do not allow generation commands to generate outside selection

commit 2485f5eccc
Author: dordsor21 <dordsor21@gmail.com>
Date:   Fri Jul 16 10:43:15 2021 +0100

    EditSession needs to override some Extent methods to ensure block changes are correctly set through the various extents
    Fixes #1152

commit d9418ec8ae
Author: dordsor21 <dordsor21@gmail.com>
Date:   Fri Jul 16 09:52:44 2021 +0100

    Undo part of 41073bb1a0
    Fixes #1178

* Update Upstream

fb1fb84 Fixed typo and grammar

* We don't support custom heights yet

* Casing inconsistency

* Address a few comments

* Address comments

* Don't refactor to AP classpath

* Document annotation style

* Refactoring & shade cleanup

* Address a few comments

* More work

* Resolve comments not being resolved yet

* Feature/main/propagate diff annotations (#1187) (#1194)

* Remove beta package, fix history packages, move classes out of object package

* Resolve comments not being resolved yet

* Remove beta package, fix history packages, move classes out of object package

Co-authored-by: NotMyFault <mc.cache@web.de>

* brushes should be under brush

* More refactoring
 - Filters/processors should be in the same place and are related to extents
 - Transforms are in `extent.transform` in upstream

* Move history classes under history

* Update adapters

Co-authored-by: dordsor21 <dordsor21@gmail.com>
This commit is contained in:
NotMyFault
2021-07-23 17:48:51 +02:00
committed by GitHub
parent ad102ab7a9
commit 50ab8ad5c7
799 changed files with 4916 additions and 10589 deletions

View File

@ -20,25 +20,25 @@
package com.sk89q.worldedit;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.beta.implementation.lighting.NullRelighter;
import com.fastasyncworldedit.core.beta.implementation.lighting.Relighter;
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
import com.fastasyncworldedit.core.extent.processor.lighting.Relighter;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.object.FaweLimit;
import com.fastasyncworldedit.core.object.RegionWrapper;
import com.fastasyncworldedit.core.object.RunnableVal;
import com.fastasyncworldedit.core.object.changeset.AbstractChangeSet;
import com.fastasyncworldedit.core.object.changeset.BlockBagChangeSet;
import com.fastasyncworldedit.core.object.clipboard.WorldCopyClipboard;
import com.fastasyncworldedit.core.object.collection.LocalBlockVectorSet;
import com.fastasyncworldedit.core.object.extent.FaweRegionExtent;
import com.fastasyncworldedit.core.object.extent.ProcessedWEExtent;
import com.fastasyncworldedit.core.object.extent.ResettableExtent;
import com.fastasyncworldedit.core.object.extent.SingleRegionExtent;
import com.fastasyncworldedit.core.object.extent.SourceMaskExtent;
import com.fastasyncworldedit.core.object.function.SurfaceRegionFunction;
import com.fastasyncworldedit.core.object.mask.ResettableMask;
import com.fastasyncworldedit.core.object.pattern.ExistingPattern;
import com.fastasyncworldedit.core.regions.RegionWrapper;
import com.fastasyncworldedit.core.util.task.RunnableVal;
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
import com.fastasyncworldedit.core.history.changeset.BlockBagChangeSet;
import com.fastasyncworldedit.core.extent.clipboard.WorldCopyClipboard;
import com.fastasyncworldedit.core.math.LocalBlockVectorSet;
import com.fastasyncworldedit.core.extent.FaweRegionExtent;
import com.fastasyncworldedit.core.extent.ProcessedWEExtent;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.SingleRegionExtent;
import com.fastasyncworldedit.core.extent.SourceMaskExtent;
import com.fastasyncworldedit.core.function.SurfaceRegionFunction;
import com.fastasyncworldedit.core.function.mask.ResettableMask;
import com.fastasyncworldedit.core.function.pattern.ExistingPattern;
import com.fastasyncworldedit.core.util.EditSessionBuilder;
import com.fastasyncworldedit.core.util.ExtentTraverser;
import com.fastasyncworldedit.core.util.MaskTraverser;
@ -52,42 +52,41 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent;
import com.sk89q.worldedit.extent.PassthroughExtent;
import com.fastasyncworldedit.core.extent.PassthroughExtent;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
import com.sk89q.worldedit.extent.world.WatchdogTickingExtent;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.block.SnowSimulator;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.generator.GenBase;
import com.sk89q.worldedit.function.generator.OreGen;
import com.sk89q.worldedit.function.generator.SchemGen;
import com.fastasyncworldedit.core.function.mask.BlockMaskBuilder;
import com.fastasyncworldedit.core.function.generator.GenBase;
import com.fastasyncworldedit.core.function.generator.OreGen;
import com.fastasyncworldedit.core.function.generator.SchemGen;
import com.sk89q.worldedit.function.mask.BlockStateMask;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.mask.BoundedHeightMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.mask.MaskUnion;
import com.fastasyncworldedit.core.function.mask.MaskUnion;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.mask.RegionMask;
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
import com.sk89q.worldedit.function.mask.SolidBlockMask;
import com.sk89q.worldedit.function.mask.WallMakeMask;
import com.fastasyncworldedit.core.function.mask.SingleBlockTypeMask;
import com.fastasyncworldedit.core.function.mask.WallMakeMask;
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.WaterloggedRemover;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DirectionalVisitor;
import com.fastasyncworldedit.core.function.visitor.DirectionalVisitor;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
@ -105,8 +104,8 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.MathUtils;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.MutableBlockVector3;
import com.fastasyncworldedit.core.math.MutableBlockVector2;
import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.sk89q.worldedit.math.Vector2;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.interpolation.Interpolation;
@ -174,7 +173,12 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
* using the {@link ChangeSetExtent}.</p>
*/
@SuppressWarnings({"FieldCanBeLocal"})
/* FAWE start - extends PassthroughExtent > implements Extent
Make sure, that all edits go thru it, else history etc. can have issues.
PassthroughExtent has some for loops that then delegate to methods editsession overrides.
*/
public class EditSession extends PassthroughExtent implements AutoCloseable {
//FAWE end
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -215,24 +219,27 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
@SuppressWarnings("ProtectedField")
protected final World world;
//FAWE start
private final FaweLimit originalLimit;
private final FaweLimit limit;
private final Player player;
private AbstractChangeSet changeSet;
private boolean history;
private final MutableBlockVector3 mutablebv = new MutableBlockVector3();
private final MutableBlockVector3 mutableBlockVector3 = new MutableBlockVector3();
private int changes = 0;
private final BlockBag blockBag;
private final Extent bypassHistory;
private Extent bypassAll;
private final Extent bypassAll;
private final int minY;
private final int maxY;
//FAWE end
private final List<WatchdogTickingExtent> watchdogExtents = new ArrayList<>(2);
//FAWE start
private final Relighter relighter;
private final boolean wnaMode;
@ -247,6 +254,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
@Nullable BlockBag blockBag, @Nullable EditSessionEvent event) {
this(new EditSessionBuilder(world).player(player).limit(limit).changeSet(changeSet).allowedRegions(allowedRegions).autoQueue(autoQueue).fastmode(fastmode).checkMemory(checkMemory).combineStages(combineStages).blockBag(blockBag).eventBus(bus).event(event));
}
//FAWE end
/**
* Construct the object with a maximum number of blocks and a block bag.
@ -257,6 +265,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @param blockBag an optional {@link BlockBag} to use, otherwise null
* @param event the event to call with the extent
*/
//FAWE start - EditSessionEvent
public EditSession(@NotNull EventBus eventBus, World world, int maxBlocks, @Nullable BlockBag blockBag, EditSessionEvent event) {
this(eventBus, world, null, null, null, null, true, null, null, null, blockBag, event);
}
@ -359,6 +368,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
boolean commitRequired() {
return false;
}
//FAWE end
/**
* Turns on specific features for a normal WorldEdit session, such as
@ -375,6 +385,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @param reorderMode The reorder mode
*/
public void setReorderMode(ReorderMode reorderMode) {
//FAWE start - we don't do physics so we don't need this
switch (reorderMode) {
case MULTI_STAGE:
enableQueue();
@ -386,6 +397,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
default:
throw new UnsupportedOperationException("Not implemented: " + reorderMode);
}
//FAWE end
}
/**
@ -457,7 +469,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
@Deprecated
public boolean isQueueEnabled() {
//FAWE start - see reorder comment, we don't need this
return true;
//FAWE end
}
/**
@ -468,7 +482,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
@Deprecated
public void enableQueue() {
//FAWE start - see reorder comment, we don't need this
super.enableQueue();
//FAWE end
}
/**
@ -476,7 +492,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
@Deprecated
public void disableQueue() {
//FAWE start - see reorder comment, we don't need this
super.disableQueue();
//FAWE end
}
/**
@ -485,14 +503,17 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @return mask, may be null
*/
public Mask getMask() {
//FAWE start - ExtendTraverser & MaskingExtents
ExtentTraverser<MaskingExtent> maskingExtent = new ExtentTraverser<>(getExtent()).find(MaskingExtent.class);
return maskingExtent != null ? maskingExtent.get().getMask() : null;
//FAWE end
}
//FAWE start
/**
* Get the mask.
* Get the source mask.
*
* @return mask, may be null
* @return source mask, may be null
*/
public Mask getSourceMask() {
ExtentTraverser<SourceMaskExtent> maskingExtent = new ExtentTraverser<>(getExtent()).find(SourceMaskExtent.class);
@ -518,7 +539,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return null;
}
//FAWE end
//FAWE start - use source mast > mask
/**
* Set a mask.
*
@ -558,7 +581,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
setSourceMask(mask);
}
//FAWE end
//FAWE start - use MaskingExtent & ExtentTraverser
/**
* Set a mask.
*
@ -581,7 +606,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
addProcessor(new MaskingExtent(getExtent(), mask));
}
}
//FAWE end
//FAWE start - ExtentTraverser
/**
* Get the {@link SurvivalModeExtent}.
*
@ -597,7 +624,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return survival;
}
}
//FAWE end
//FAWE start - our fastmode works different to upstream
/**
* Set whether fast mode is enabled.
*
@ -610,7 +639,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public void setFastMode(boolean enabled) {
disableHistory(enabled);
}
//FAWE end
//FAWE start - we don't use this (yet)
/**
* Set which block updates should occur.
*
@ -624,7 +655,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
//Do nothing; TODO: SideEffects currently not fully implemented in FAWE.
return SideEffectSet.defaults();
}
//FAWE end
//FAWE start
/**
* Disable history (or re-enable)
*
@ -646,7 +679,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
}
}
//FAWE end
//FAWE start - See comment on setFastMode
/**
* Return fast mode status.
*
@ -659,7 +694,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public boolean hasFastMode() {
return getChangeSet() == null;
}
//FAWE end
//FAWE start - Don't use blockBagExtent
/**
* Get the {@link BlockBag} is used.
*
@ -668,7 +705,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public BlockBag getBlockBag() {
return this.blockBag;
}
//FAWE end
//FAWE start
/**
* Set a {@link BlockBag} to use.
*
@ -678,7 +717,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
//Not Supported in FAWE
throw new UnsupportedOperationException("TODO - this is never called anyway");
}
//FAWE end
//FAWE start
@Override
public String toString() {
return super.toString() + ":" + getExtent();
@ -730,7 +771,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return Collections.emptyMap();
}
//FAWE end
//FAWE start - We don't use this method
/**
* Returns chunk batching status.
*
@ -739,6 +782,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public boolean isBatchingChunks() {
return false;
}
//FAWE end
/**
* Enable or disable chunk batching. Disabling will flush the session.
@ -746,11 +790,13 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @param batchingChunks {@code true} to enable, {@code false} to disable
*/
public void setBatchingChunks(boolean batchingChunks) {
//FAWE start - altered by our lifecycle
if (batchingChunks) {
enableQueue();
} else {
disableQueue();
}
//FAWE end
}
/**
@ -760,7 +806,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @see #setBatchingChunks(boolean)
*/
public void disableBuffering() {
//FAWE start - see comment on reorder mode
disableQueue();
//FAWE end
}
/**
@ -804,20 +852,24 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
//FAWE start - use extent
if (position.getY() < this.minY || position.getY() > this.maxY) {
return false;
}
this.changes++;
return this.getExtent().setBiome(position, biome);
//FAWE end
}
@Override
public boolean setBiome(int x, int y, int z, BiomeType biome) {
//FAWE start - use extent
if (y < this.minY || y > this.maxY) {
return false;
}
this.changes++;
return this.getExtent().setBiome(x, y, z, biome);
//FAWE end
}
/**
@ -830,10 +882,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @return height of highest block found or 'minY'
*/
public int getHighestTerrainBlock(int x, int z, int minY, int maxY) {
//FAWE start - check movement blocker
for (int y = maxY; y >= minY; --y) {
if (getBlock(x, y, z).getBlockType().getMaterial().isMovementBlocker()) {
return y;
}
//FAWE end
}
return minY;
}
@ -850,7 +904,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) {
for (int y = maxY; y >= minY; --y) {
if (filter.test(mutablebv.setComponents(x, y, z))) {
//FAWE start - get position from mutable vector
if (filter.test(mutableBlockVector3.setComponents(x, y, z))) {
//FAWE end
return y;
}
}
@ -858,9 +914,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return minY;
}
//FAWE start
public BlockType getBlockType(int x, int y, int z) {
return getBlock(x, y, z).getBlockType();
}
//FAWE end
/**
* Set a block, bypassing both history and block re-ordering.
@ -873,6 +931,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
@Deprecated
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, Stage stage) throws WorldEditException {
//FAWE start - accumulate changes
if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) {
return false;
}
@ -886,10 +945,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
case BEFORE_REORDER:
return bypassAll.setBlock(position, block);
}
//FAWE end
throw new RuntimeException("New enum entry added that is unhandled here");
}
//FAWE start - see former comment
/**
* Set a block, bypassing both history and block re-ordering.
*
@ -910,7 +971,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
throw new RuntimeException("Unexpected exception", e);
}
}
//FAWE end
//FAWE start - we use this
/**
* Set a block, bypassing history but still utilizing block re-ordering.
*
@ -980,7 +1043,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
this.changes++;
try {
BlockVector3 bv = mutablebv.setComponents(x, y, z);
BlockVector3 bv = mutableBlockVector3.setComponents(x, y, z);
return pattern.apply(getExtent(), bv, bv);
} catch (WorldEditException e) {
throw new RuntimeException("Unexpected exception", e);
@ -1017,7 +1080,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
return this.changes = super.setBlocks(region, pattern);
}
//FAWE end
//FAWE start
/**
* Restores all blocks to their initial state.
*
@ -1025,6 +1090,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
public void undo(EditSession editSession) {
UndoContext context = new UndoContext();
//FAWE start - listen for inventory, flush & prepare changeset
context.setExtent(editSession.bypassAll);
ChangeSet changeSet = getChangeSet();
setChangeSet(null);
@ -1033,6 +1099,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
editSession.changes = 1;
}
//FAWE start
public void setBlocks(ChangeSet changeSet, ChangeSetExecutor.Type type) {
final UndoContext context = new UndoContext();
context.setExtent(bypassAll);
@ -1040,6 +1107,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
flushQueue();
changes = 1;
}
//FAWE end
/**
* Sets to new state.
@ -1048,6 +1116,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
*/
public void redo(EditSession editSession) {
UndoContext context = new UndoContext();
//FAWE start - listen for inventory, flush & prepare changeset
context.setExtent(editSession.bypassAll);
ChangeSet changeSet = getChangeSet();
setChangeSet(null);
@ -1055,6 +1124,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
flushQueue();
editSession.changes = 1;
}
//FAWE end
/**
* Get the number of changed blocks.
@ -1065,9 +1135,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return getBlockChangeCount();
}
//FAWE start
public void setSize(int size) {
this.changes = size;
}
//FAWE end
/**
* Closing an EditSession flushes its buffers to the world, and performs other
@ -1089,6 +1161,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
flushQueue();
}
//FAWE start
/**
* Finish off the queue.
*/
@ -1222,6 +1295,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
}
//FAWE end
/**
* Fills an area recursively in the X/Z directions.
@ -1279,7 +1353,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
// Execute
Operations.completeLegacy(visitor);
//FAWE start
return this.changes = visitor.getAffected();
//FAWE end
}
/**
@ -1449,13 +1525,16 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
checkNotNull(region);
checkNotNull(pattern);
//FAWE start
int blocksChanged = 0;
for (Region wall : CuboidRegion.makeCuboid(region).getWalls().getRegions()) {
blocksChanged += setBlocks(wall, pattern);
}
return blocksChanged;
//FAWE end
}
//FAWE start
/**
* Make the walls of the given region. The method by which the walls are found
* may be inefficient, because there may not be an efficient implementation supported
@ -1477,6 +1556,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return changes;
}
//FAWE end
/**
* Places a layer of blocks on top of ground blocks in the given region
@ -1510,10 +1590,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
BlockReplace replace = new BlockReplace(this, pattern);
RegionOffset offset = new RegionOffset(BlockVector3.UNIT_Y, replace);
//FAWE start
int minY = region.getMinimumPoint().getBlockY();
int maxY = Math.min(getMaximumPoint().getBlockY(), region.getMaximumPoint().getBlockY() + 1);
SurfaceRegionFunction surface = new SurfaceRegionFunction(this, offset, minY, maxY);
FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface);
//FAWE end
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
}
@ -1551,6 +1633,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return stackCuboidRegion(region, dir, count, true, false, copyAir ? null : new ExistingBlockMask(this));
}
//FAWE start
/**
* Stack a cuboid region.
*
@ -1590,6 +1673,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
Operations.completeLegacy(copy);
return this.changes = copy.getAffected();
}
//FAWE end
/**
* Move the blocks in a region a certain direction.
@ -1605,11 +1689,13 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int moveRegion(Region region, BlockVector3 dir, int distance, boolean copyAir, boolean moveEntities, boolean copyBiomes, Pattern replacement) throws MaxChangedBlocksException {
//FAWE start
Mask mask = null;
if (!copyAir) {
mask = new ExistingBlockMask(this);
}
return moveRegion(region, dir, distance, moveEntities, copyBiomes, mask, replacement);
//FAWE end
}
/**
@ -1633,6 +1719,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
checkArgument(distance >= 1, "distance >= 1 required");
checkArgument(!copyBiomes || region instanceof FlatRegion, "can't copy biomes from non-flat region");
//FAWE start - add up distance
BlockVector3 to = region.getMinimumPoint().add(dir.multiply(distance));
final BlockVector3 displace = dir.multiply(distance);
@ -1673,6 +1760,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
Operations.completeBlindly(copy);
return this.changes = copy.getAffected();
//FAWE end
}
/**
@ -1729,22 +1817,30 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
//FAWE start - liquidmask
Mask liquidMask;
if (plants) {
liquidMask = new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER,
BlockTypes.KELP_PLANT, BlockTypes.KELP, BlockTypes.SEAGRASS, BlockTypes.TALL_SEAGRASS);
BlockTypes.KELP_PLANT, BlockTypes.KELP, BlockTypes.SEAGRASS, BlockTypes.TALL_SEAGRASS);
} else {
liquidMask = new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
liquidMask = new BlockMaskBuilder()
.addTypes(BlockTypes.WATER, BlockTypes.LAVA)
.build(this);
}
//FAWE end
if (waterlogged) {
Map<String, String> stateMap = new HashMap<>();
stateMap.put("waterlogged", "true");
//FAWE start
liquidMask = new MaskUnion(liquidMask, new BlockStateMask(this, stateMap, true));
//FAWE end
}
Mask mask = new MaskIntersection(
new BoundedHeightMask(0, getWorld().getMaxY()),
new BoundedHeightMask(getWorld().getMinY(), getWorld().getMaxY()),
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
//FAWE start
liquidMask);
//FAWE end
BlockReplace replace;
if (waterlogged) {
replace = new BlockReplace(this, new WaterloggedRemover(this));
@ -1762,7 +1858,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
Operations.completeLegacy(visitor);
//FAWE start
return this.changes = visitor.getAffected();
//FAWE end
}
/**
@ -1786,7 +1884,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
// There are boundaries that the routine needs to stay in
Mask mask = new MaskIntersection(
new BoundedHeightMask(0, Math.min(origin.getBlockY(), getWorld().getMaxY())),
new BoundedHeightMask(getWorld().getMinY(), Math.min(origin.getBlockY(), getWorld().getMaxY())),
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
blockMask
);
@ -1837,34 +1935,43 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return makeCylinder(pos, block, radiusX, radiusZ, height, 0, filled);
}
//FAWE start
public int makeHollowCylinder(BlockVector3 pos, final Pattern block, double radiusX, double radiusZ, int height, double thickness) throws MaxChangedBlocksException {
return makeCylinder(pos, block, radiusX, radiusZ, height, thickness, false);
}
//FAWE end
private int makeCylinder(BlockVector3 pos, Pattern block, double radiusX, double radiusZ, int height, double thickness, boolean filled) throws MaxChangedBlocksException {
public int makeCylinder(BlockVector3 pos, Pattern block, double radiusX, double radiusZ, int height, double thickness, boolean filled) throws MaxChangedBlocksException {
radiusX += 0.5;
radiusZ += 0.5;
MutableBlockVector3 posv = new MutableBlockVector3(pos);
//FAWE start
MutableBlockVector3 mutableBlockVector3 = new MutableBlockVector3(pos);
//FAWE end
if (height == 0) {
return 0;
} else if (height < 0) {
height = -height;
posv.mutY(posv.getY() - height);
//FAWE start
mutableBlockVector3.mutY(mutableBlockVector3.getY() - height);
//FAWE end
}
if (posv.getBlockY() < 0) {
posv.mutY(0);
} else if (posv.getBlockY() + height - 1 > maxY) {
height = maxY - posv.getBlockY() + 1;
//FAWE start
if (mutableBlockVector3.getBlockY() < getWorld().getMinY()) {
mutableBlockVector3.mutY(world.getMinY());
} else if (mutableBlockVector3.getBlockY() + height - 1 > maxY) {
height = maxY - mutableBlockVector3.getBlockY() + 1;
}
//FAWE end
final double invRadiusX = 1 / radiusX;
final double invRadiusZ = 1 / radiusZ;
int px = posv.getBlockX();
int py = posv.getBlockY();
int pz = posv.getBlockZ();
//FAWE start
int px = mutableBlockVector3.getBlockX();
int py = mutableBlockVector3.getBlockY();
int pz = mutableBlockVector3.getBlockZ();
MutableBlockVector3 mutable = new MutableBlockVector3();
final int ceilRadiusX = (int) Math.ceil(radiusX);
@ -1914,6 +2021,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
}
} else {
//FAWE end
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
final double xn = nextXn;
nextXn = (x + 1) * invRadiusX;
@ -1938,16 +2046,20 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
for (int y = 0; y < height; ++y) {
//FAWE start - mutable
this.setBlock(mutable.setComponents(px + x, py + y, pz + z), block);
this.setBlock(mutable.setComponents(px - x, py + y, pz + z), block);
this.setBlock(mutable.setComponents(px + x, py + y, pz - z), block);
this.setBlock(mutable.setComponents(px - x, py + y, pz - z), block);
//FAWE end
}
}
}
}
//FAWE start
return this.changes;
//FAWE end
}
/**
@ -1965,6 +2077,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return moveRegion(region, dir, distance, true, false, copyAir ? new ExistingBlockMask(this) : null, replacement);
}
//FAWE start
public int makeCircle(BlockVector3 pos, final Pattern block, double radiusX, double radiusY, double radiusZ, boolean filled, Vector3 normal) throws MaxChangedBlocksException {
radiusX += 0.5;
radiusY += 0.5;
@ -2061,6 +2174,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return changes;
}
//FAWE end
/**
* Makes a sphere.
@ -2105,7 +2219,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
final int ceilRadiusY = (int) Math.ceil(radiusY);
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
//FAWE start
int yy;
//FAWE end
double nextXn = 0;
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
@ -2141,6 +2257,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
continue;
}
}
//FAWE start
yy = py + y;
if (yy <= maxY) {
this.setBlock(px + x, py + y, pz + z, block);
@ -2171,6 +2288,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return changes;
//FAWE end
}
/**
@ -2184,6 +2302,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makePyramid(BlockVector3 position, Pattern block, int size, boolean filled) throws MaxChangedBlocksException {
//FAWE start - abbreviated logic
int bx = position.getX();
int by = position.getY();
int bz = position.getZ();
@ -2206,6 +2325,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return changes;
//FAWE end
}
/**
@ -2266,6 +2386,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
++affected;
}
} else if (id == BlockTypes.SNOW) {
//FAWE start
if (setBlock(pt, air)) {
if (y > 0 ) {
BlockState block = getBlock(below);
@ -2275,6 +2396,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
}
}
//FAWE end
++affected;
}
} else if (id.getMaterial().isAir()) {
@ -2419,6 +2541,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return makePumpkinPatches(position, apothem, 0.02);
}
//FAWE start - support density
public int makePumpkinPatches(BlockVector3 position, int apothem, double density) throws MaxChangedBlocksException {
// We want to generate pumpkins
GardenPatchGenerator generator = new GardenPatchGenerator(this);
@ -2436,6 +2559,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
Operations.completeLegacy(visitor);
return this.changes = ground.getAffected();
}
//FAWE end
/**
* Makes a forest.
@ -2476,6 +2600,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @return the results
*/
public List<Countable<BlockState>> getBlockDistribution(Region region, boolean separateStates) {
//FAWE start - get distr
if (separateStates) {
return getBlockDistributionWithData(region);
}
@ -2484,6 +2609,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
for (Countable<BlockType> count : normalDistr) {
distribution.add(new Countable<>(count.getID().getDefaultState(), count.getAmount()));
}
//FAWE end
return distribution;
}
@ -2631,41 +2757,40 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(this, unit, zero);
expression.setEnvironment(environment);
//FAWE start
final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
RegionVisitor visitor = new RegionVisitor(region, position -> {
try {
// offset, scale
final Vector3 scaled = position.toVector3().subtract(zero).divide(unit);
@Override
public boolean apply(BlockVector3 position) throws WorldEditException {
try {
// offset, scale
final Vector3 scaled = position.toVector3().subtract(zero).divide(unit);
// transform
expression.evaluate(new double[]{scaled.getX(), scaled.getY(), scaled.getZ()}, timeout);
int xv = (int) (x.getValue() * unit.getX() + zero2.getX());
int yv = (int) (y.getValue() * unit.getY() + zero2.getY());
int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ());
// transform
expression.evaluate(new double[]{scaled.getX(), scaled.getY(), scaled.getZ()}, timeout);
int xv = (int) (x.getValue() * unit.getX() + zero2.getX());
int yv = (int) (y.getValue() * unit.getY() + zero2.getY());
int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ());
BlockState get;
if (yv >= 0 && yv < 256) {
get = getBlock(xv, yv, zv);
} else {
get = BlockTypes.AIR.getDefaultState();
}
// read block from world
return setBlock(position, get);
} catch (EvaluationException e) {
throw new RuntimeException(e);
BlockState get;
if (yv >= 0 && yv < 256) {
get = getBlock(xv, yv, zv);
} else {
get = BlockTypes.AIR.getDefaultState();
}
// read block from world
return setBlock(position, get);
} catch (EvaluationException e) {
throw new RuntimeException(e);
}
});
Operations.completeBlindly(visitor);
changes += visitor.getAffected();
return changes;
//FAWE end
}
//FAWE start - respect Mask
/**
* Hollows out the region (Semi-well-defined for non-cuboid selections).
*
@ -2676,10 +2801,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int hollowOutRegion(Region region, int thickness, Pattern pattern) throws MaxChangedBlocksException {
return hollowOutRegion(region, thickness, pattern, new SolidBlockMask(this));
}
public int hollowOutRegion(Region region, int thickness, Pattern pattern, Mask mask) {
try {
final Set<BlockVector3> outside = new LocalBlockVectorSet();
@ -2747,6 +2868,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return changes;
}
//FAWE end
public int drawLine(Pattern pattern, BlockVector3 pos1, BlockVector3 pos2, double radius, boolean filled) throws MaxChangedBlocksException {
return drawLine(pattern, pos1, pos2, radius, filled, false);
@ -2770,7 +2892,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
throws MaxChangedBlocksException {
LocalBlockVectorSet vset = new LocalBlockVectorSet();
//FAWE start
boolean notdrawn = true;
//FAWE end
int x1 = pos1.getBlockX();
int y1 = pos1.getBlockY();
@ -2787,11 +2911,15 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
if (dx + dy + dz == 0) {
vset.add(BlockVector3.at(tipx, tipy, tipz));
//FAWE start
notdrawn = false;
//FAWE end
}
int dMax = Math.max(Math.max(dx, dy), dz);
//FAWE start - notdrawn
if (dMax == dx && notdrawn) {
//FAWE end
for (int domstep = 0; domstep <= dx; domstep++) {
tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1);
tipy = (int) Math.round(y1 + domstep * (double) dy / (double) dx * (y2 - y1 > 0 ? 1 : -1));
@ -2799,7 +2927,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
vset.add(BlockVector3.at(tipx, tipy, tipz));
}
//FAWE start - notdrawn
} else if (dMax == dy && notdrawn) {
//FAWE end
for (int domstep = 0; domstep <= dy; domstep++) {
tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1);
tipx = (int) Math.round(x1 + domstep * (double) dx / (double) dy * (x2 - x1 > 0 ? 1 : -1));
@ -2807,7 +2937,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
vset.add(BlockVector3.at(tipx, tipy, tipz));
}
//FAWE start - notdrawn
} else if (dMax == dz && notdrawn) {
//FAWE end
for (int domstep = 0; domstep <= dz; domstep++) {
tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1);
tipy = (int) Math.round(y1 + domstep * (double) dy / (double) dz * (y2 - y1 > 0 ? 1 : -1));
@ -2816,6 +2948,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
vset.add(BlockVector3.at(tipx, tipy, tipz));
}
}
//FAWE start - set BV3
Set<BlockVector3> newVset;
if (flat) {
newVset = getStretched(vset, radius);
@ -2829,6 +2962,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
}
return this.changes += setBlocks(newVset, pattern);
//FAWE end
}
/**
@ -2983,6 +3117,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return returnset;
}
//FAWE start
public static Set<BlockVector3> getStretched(Set<BlockVector3> vset, double radius) {
if (radius < 1) {
return vset;
@ -3021,6 +3156,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
}
return returnset;
}
//FAWE end
public Set<BlockVector3> getHollowed(Set<BlockVector3> vset) {
final Set<BlockVector3> returnset = new LocalBlockVectorSet();
@ -3126,6 +3262,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
Direction.DOWN.toBlockVector(),
};
//FAWE start
public boolean regenerate(Region region) {
return regenerate(region, this);
}
@ -3298,4 +3435,5 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
faweClipboard.setOrigin(region.getMinimumPoint());
return faweClipboard;
}
//FAWE end
}