Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-26 11:00:04 +01:00
extend to lazy clipboard
Dieser Commit ist enthalten in:
Ursprung
6f83adcff0
Commit
1da41a70ac
@ -52,12 +52,12 @@ public class OncePerChunkExtent extends AbstractDelegateExtent implements IBatch
|
||||
}
|
||||
|
||||
private boolean shouldRun(int chunkX, int chunkZ) {
|
||||
final long pair = (long) chunkX << 32 | chunkZ & 0xffffffffL;
|
||||
if (pair == lastPair) {
|
||||
return false;
|
||||
}
|
||||
lastPair = pair;
|
||||
synchronized (set) {
|
||||
final long pair = (long) chunkX << 32 | chunkZ & 0xffffffffL;
|
||||
if (pair == lastPair) {
|
||||
return false;
|
||||
}
|
||||
lastPair = pair;
|
||||
return set.add(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
@ -68,10 +68,16 @@ public class OncePerChunkExtent extends AbstractDelegateExtent implements IBatch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the task run once per chunk.
|
||||
*/
|
||||
public Consumer<IChunkGet> getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the task to be run once per chunk
|
||||
*/
|
||||
public void setTask(Consumer<IChunkGet> task) {
|
||||
this.task = task;
|
||||
}
|
||||
@ -181,4 +187,12 @@ public class OncePerChunkExtent extends AbstractDelegateExtent implements IBatch
|
||||
super.setSkyLight(x, y, z, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the chunks visited
|
||||
*/
|
||||
public void reset() {
|
||||
lastPair = Long.MAX_VALUE;
|
||||
set.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,17 +45,17 @@ public abstract class ReadOnlyClipboard extends SimpleClipboard {
|
||||
return of(() -> extent, region);
|
||||
}
|
||||
|
||||
public static ReadOnlyClipboard of(Extent extent, final Region region, boolean copyEntities, boolean copyBiomes) {
|
||||
Fawe.instance().getQueueHandler().unCache();
|
||||
return of(() -> extent, region, copyEntities, copyBiomes);
|
||||
}
|
||||
|
||||
public static ReadOnlyClipboard of(Supplier<Extent> supplier, final Region region) {
|
||||
return of(supplier, region, true, false);
|
||||
}
|
||||
|
||||
public static ReadOnlyClipboard of(Supplier<Extent> supplier, final Region region, boolean copyEntities, boolean copyBiomes) {
|
||||
return new WorldCopyClipboard(supplier, region, copyEntities, copyBiomes);
|
||||
return of(supplier.get(), region, copyEntities, copyBiomes);
|
||||
}
|
||||
|
||||
public static ReadOnlyClipboard of(Extent extent, final Region region, boolean copyEntities, boolean copyBiomes) {
|
||||
Fawe.instance().getQueueHandler().unCache();
|
||||
return WorldCopyClipboard.of(extent, region, copyEntities, copyBiomes);
|
||||
}
|
||||
|
||||
private static Supplier<Extent> supply() {
|
||||
|
@ -1,14 +1,22 @@
|
||||
package com.fastasyncworldedit.core.extent.clipboard;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EditSessionBuilder;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ -16,26 +24,47 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
|
||||
|
||||
private final boolean hasBiomes;
|
||||
private final boolean hasEntities;
|
||||
private Extent extent;
|
||||
private Supplier<Extent> supplier;
|
||||
private final Extent extent;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link WorldCopyClipboard#of(Extent, Region)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "TODO")
|
||||
public WorldCopyClipboard(Supplier<Extent> supplier, Region region) {
|
||||
this(supplier, region, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link WorldCopyClipboard#of(Extent, Region, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "TODO")
|
||||
public WorldCopyClipboard(Supplier<Extent> supplier, Region region, boolean hasEntities, boolean hasBiomes) {
|
||||
super(region);
|
||||
this.hasBiomes = hasBiomes;
|
||||
this.hasEntities = hasEntities;
|
||||
this.supplier = supplier;
|
||||
this.extent = supplier.get();
|
||||
}
|
||||
|
||||
private WorldCopyClipboard(Extent extent, Region region, boolean hasEntities, boolean hasBiomes) {
|
||||
super(region);
|
||||
this.hasBiomes = hasBiomes;
|
||||
this.hasEntities = hasEntities;
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
public static WorldCopyClipboard of(Extent extent, Region region) {
|
||||
return of(extent, region, true);
|
||||
}
|
||||
|
||||
public static WorldCopyClipboard of(Extent extent, Region region, boolean hasEntities) {
|
||||
return of(extent, region, hasEntities, false);
|
||||
}
|
||||
|
||||
public static WorldCopyClipboard of(Extent extent, Region region, boolean hasEntities, boolean hasBiomes) {
|
||||
return new WorldCopyClipboard(extent, region, hasEntities, hasBiomes);
|
||||
}
|
||||
|
||||
public Extent getExtent() {
|
||||
if (extent != null) {
|
||||
return extent;
|
||||
}
|
||||
extent = supplier.get();
|
||||
supplier = null;
|
||||
return extent;
|
||||
}
|
||||
|
||||
@ -60,6 +89,7 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<? extends Entity> getEntities() {
|
||||
if (!hasEntities) {
|
||||
return new ArrayList<>();
|
||||
@ -72,4 +102,69 @@ public class WorldCopyClipboard extends ReadOnlyClipboard {
|
||||
return hasBiomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Extent toExtent, BlockVector3 to, boolean pasteAir, boolean pasteEntities, boolean pasteBiomes) {
|
||||
boolean close = false;
|
||||
if (toExtent instanceof World) {
|
||||
close = true;
|
||||
EditSessionBuilder builder = WorldEdit
|
||||
.getInstance()
|
||||
.newEditSessionBuilder()
|
||||
.world((World) toExtent)
|
||||
.checkMemory(false)
|
||||
.allowedRegionsEverywhere()
|
||||
.limitUnlimited()
|
||||
.changeSetNull();
|
||||
toExtent = builder.build();
|
||||
}
|
||||
|
||||
Extent source = getExtent();
|
||||
|
||||
Collection<Entity> entities = pasteEntities ? ForwardExtentCopy.getEntities(source, region) : Collections.emptySet();
|
||||
|
||||
final BlockVector3 origin = this.getOrigin();
|
||||
|
||||
// To must be relative to the clipboard origin ( player location - clipboard origin ) (as the locations supplied are relative to the world origin)
|
||||
final int relx = to.getBlockX() - origin.getBlockX();
|
||||
final int rely = to.getBlockY() - origin.getBlockY();
|
||||
final int relz = to.getBlockZ() - origin.getBlockZ();
|
||||
|
||||
pasteBiomes &= this.hasBiomes();
|
||||
|
||||
for (BlockVector3 pos : this) {
|
||||
BaseBlock block = pos.getFullBlock(this);
|
||||
int xx = pos.getX() + relx;
|
||||
int yy = pos.getY() + rely;
|
||||
int zz = pos.getZ() + relz;
|
||||
if (pasteBiomes) {
|
||||
toExtent.setBiome(xx, yy, zz, pos.getBiome(this));
|
||||
}
|
||||
if (!pasteAir && block.getBlockType().getMaterial().isAir()) {
|
||||
continue;
|
||||
}
|
||||
toExtent.setBlock(xx, yy, zz, block);
|
||||
}
|
||||
// Entity offset is the paste location subtract the clipboard origin (entity's location is already relative to the world origin)
|
||||
final int entityOffsetX = to.getBlockX() - origin.getBlockX();
|
||||
final int entityOffsetY = to.getBlockY() - origin.getBlockY();
|
||||
final int entityOffsetZ = to.getBlockZ() - origin.getBlockZ();
|
||||
// entities
|
||||
for (Entity entity : entities) {
|
||||
// skip players on pasting schematic
|
||||
if (entity.getState() != null && entity.getState().getType().getId()
|
||||
.equals("minecraft:player")) {
|
||||
continue;
|
||||
}
|
||||
Location pos = entity.getLocation();
|
||||
Location newPos = new Location(pos.getExtent(), pos.getX() + entityOffsetX,
|
||||
pos.getY() + entityOffsetY, pos.getZ() + entityOffsetZ, pos.getYaw(),
|
||||
pos.getPitch()
|
||||
);
|
||||
toExtent.createEntity(newPos, entity.getState());
|
||||
}
|
||||
if (close) {
|
||||
((EditSession) toExtent).close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ public class ParallelQueueExtent extends PassthroughExtent {
|
||||
*/
|
||||
@Override
|
||||
public Clipboard lazyCopy(Region region) {
|
||||
Clipboard clipboard = new WorldCopyClipboard(() -> this, region);
|
||||
Clipboard clipboard = WorldCopyClipboard.of(this, region);
|
||||
clipboard.setOrigin(region.getMinimumPoint());
|
||||
return clipboard;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package com.fastasyncworldedit.core.util;
|
||||
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -9,6 +11,8 @@ import java.lang.reflect.Field;
|
||||
|
||||
public class ExtentTraverser<T extends Extent> {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final T root;
|
||||
private final ExtentTraverser<T> parent;
|
||||
|
||||
@ -98,9 +102,8 @@ public class ExtentTraverser<T extends Extent> {
|
||||
@SuppressWarnings("unchecked")
|
||||
public ExtentTraverser<T> next() {
|
||||
try {
|
||||
if (root instanceof AbstractDelegateExtent) {
|
||||
AbstractDelegateExtent root = (AbstractDelegateExtent) this.root;
|
||||
T value = (T) root.getExtent();
|
||||
if (root instanceof AbstractDelegateExtent abstractDelegateExtent) {
|
||||
T value = (T) abstractDelegateExtent.getExtent();
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@ -113,4 +116,23 @@ public class ExtentTraverser<T extends Extent> {
|
||||
}
|
||||
}
|
||||
|
||||
public static void printNestedExtents(Extent extent) {
|
||||
String nested = printNestedExtent(new StringBuilder("Extent tree:"), new ExtentTraverser<>(extent), 0).toString();
|
||||
LOGGER.info(nested);
|
||||
}
|
||||
|
||||
private static StringBuilder printNestedExtent(StringBuilder builder, ExtentTraverser<?> traverser, int depth) {
|
||||
if (traverser == null || !traverser.exists()) {
|
||||
return builder;
|
||||
}
|
||||
String indent = " ".repeat(Math.max(0, depth)); // Adjust the indentation as needed
|
||||
|
||||
Extent extent = traverser.get();
|
||||
builder.append("\n").append(indent).append("- ").append(extent.getClass().getSimpleName());
|
||||
|
||||
// Recursively print nested extents
|
||||
printNestedExtent(builder, traverser.next(), depth + 1);
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3927,7 +3927,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
|
||||
@Override
|
||||
public Clipboard lazyCopy(Region region) {
|
||||
WorldCopyClipboard faweClipboard = new WorldCopyClipboard(() -> this, region);
|
||||
WorldCopyClipboard faweClipboard = WorldCopyClipboard.of(this, region);
|
||||
faweClipboard.setOrigin(region.getMinimumPoint());
|
||||
return faweClipboard;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.WorldCopyClipboard;
|
||||
import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream;
|
||||
import com.fastasyncworldedit.core.limit.FaweLimit;
|
||||
import com.fastasyncworldedit.core.util.ImgurUtility;
|
||||
@ -192,7 +193,7 @@ public class ClipboardCommands {
|
||||
throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
session.setClipboard(null);
|
||||
ReadOnlyClipboard lazyClipboard = ReadOnlyClipboard.of(region, !skipEntities, copyBiomes);
|
||||
ReadOnlyClipboard lazyClipboard = WorldCopyClipboard.of(editSession, region, !skipEntities, copyBiomes);
|
||||
|
||||
lazyClipboard.setOrigin(session.getPlacementPosition(actor));
|
||||
session.setClipboard(new ClipboardHolder(lazyClipboard));
|
||||
|
@ -692,7 +692,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
* @return
|
||||
*/
|
||||
default Clipboard lazyCopy(Region region) {
|
||||
WorldCopyClipboard faweClipboard = new WorldCopyClipboard(() -> this, region);
|
||||
WorldCopyClipboard faweClipboard = WorldCopyClipboard.of(this, region);
|
||||
faweClipboard.setOrigin(region.getMinimumPoint());
|
||||
return faweClipboard;
|
||||
}
|
||||
|
@ -381,7 +381,9 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
|
||||
}
|
||||
|
||||
default void paste(Extent extent, BlockVector3 to, boolean pasteAir, boolean pasteEntities, boolean pasteBiomes) {
|
||||
boolean close = false;
|
||||
if (extent instanceof World) {
|
||||
close = true;
|
||||
EditSessionBuilder builder = WorldEdit
|
||||
.getInstance()
|
||||
.newEditSessionBuilder()
|
||||
@ -435,6 +437,9 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
|
||||
extent.createEntity(newPos, entity.getState());
|
||||
}
|
||||
}
|
||||
if (close) {
|
||||
((EditSession) extent).close();
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -24,18 +24,21 @@ import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.BlockTranslateExtent;
|
||||
import com.fastasyncworldedit.core.extent.OncePerChunkExtent;
|
||||
import com.fastasyncworldedit.core.extent.PositionTransformExtent;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.WorldCopyClipboard;
|
||||
import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder;
|
||||
import com.fastasyncworldedit.core.function.RegionMaskTestFunction;
|
||||
import com.fastasyncworldedit.core.function.block.BiomeCopy;
|
||||
import com.fastasyncworldedit.core.function.block.CombinedBlockCopy;
|
||||
import com.fastasyncworldedit.core.function.block.SimpleBlockCopy;
|
||||
import com.fastasyncworldedit.core.function.visitor.IntersectRegionFunction;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
|
||||
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
||||
import com.fastasyncworldedit.core.util.ExtentTraverser;
|
||||
import com.fastasyncworldedit.core.util.MaskTraverser;
|
||||
import com.fastasyncworldedit.core.util.ProcessorTraverser;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -57,6 +60,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Identity;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.FlatRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@ -69,7 +73,9 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -422,54 +428,7 @@ public class ForwardExtentCopy implements Operation {
|
||||
blockCopy = new RegionVisitor(region, copy, preloader);
|
||||
}
|
||||
|
||||
Collection<Entity> entities;
|
||||
if (copyingEntities) {
|
||||
IQueueExtent<IQueueChunk> queue;
|
||||
Extent ext = source instanceof AbstractDelegateExtent ex ? ex.getExtent() : source;
|
||||
ParallelQueueExtent parallel = new ExtentTraverser<>(source).findAndGet(ParallelQueueExtent.class);
|
||||
if (parallel != null) {
|
||||
queue = parallel.getExtent();
|
||||
} else {
|
||||
queue = new ExtentTraverser<>(source).findAndGet(SingleThreadQueueExtent.class);
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.IMPROVED_ENTITY_EDITS && queue != null) {
|
||||
entities = new LinkedBlockingQueue<>();
|
||||
OncePerChunkExtent oncePer = new OncePerChunkExtent(
|
||||
ext,
|
||||
queue,
|
||||
(get) -> {
|
||||
if (region.containsChunk(get.getX(), get.getZ())) {
|
||||
entities.addAll(get.getFullEntities());
|
||||
} else {
|
||||
get.getFullEntities().forEach(e -> {
|
||||
if (region.contains(e.getLocation().toBlockPoint())) {
|
||||
entities.add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
ExtentBatchProcessorHolder batchExtent =
|
||||
new ExtentTraverser<>(source).findAndGet(ExtentBatchProcessorHolder.class);
|
||||
if (batchExtent != null) {
|
||||
batchExtent.getProcessor().join(oncePer);
|
||||
} else {
|
||||
new ExtentTraverser(source).setNext(oncePer);
|
||||
}
|
||||
} else {
|
||||
if (Settings.settings().EXPERIMENTAL.IMPROVED_ENTITY_EDITS) {
|
||||
LOGGER.warn("Could not find IQueueExtent instance for entity retrieval, falling back to default method.");
|
||||
}
|
||||
// filter players since they can't be copied
|
||||
entities = new HashSet<>(source.getEntities(region));
|
||||
entities.removeIf(entity -> {
|
||||
EntityProperties properties = entity.getFacet(EntityProperties.class);
|
||||
return properties != null && !properties.isPasteable();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
entities = Collections.emptySet();
|
||||
}
|
||||
Collection<Entity> entities = copyingEntities ? getEntities(source, region) : Collections.emptySet();
|
||||
|
||||
for (int i = 0; i < repetitions; i++) {
|
||||
Operations.completeBlindly(blockCopy);
|
||||
@ -508,6 +467,78 @@ public class ForwardExtentCopy implements Operation {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If setting enabled, Creates a new OncePerChunkExtent instance to retain a list of entities for the given source extent,
|
||||
* then add it to the source extent. If setting is not set simply returns the entities from {@link Extent#getEntities()} Accepts an
|
||||
* optional region for entities to be within.
|
||||
*
|
||||
* @param source Source extent
|
||||
* @param region Optional regions for entities to be within
|
||||
* @return Collection of entities (may not be filled until an operation completes on the chunks)
|
||||
* @since TODO
|
||||
*/
|
||||
public static Collection<Entity> getEntities(Extent source, Region region) {
|
||||
Extent extent = source;
|
||||
if (source instanceof WorldCopyClipboard clip) {
|
||||
extent = clip.getExtent();
|
||||
}
|
||||
IQueueExtent<IQueueChunk> queue = null;
|
||||
if (Settings.settings().EXPERIMENTAL.IMPROVED_ENTITY_EDITS) {
|
||||
ParallelQueueExtent parallel = new ExtentTraverser<>(extent).findAndGet(ParallelQueueExtent.class);
|
||||
if (parallel != null) {
|
||||
queue = parallel.getExtent();
|
||||
} else {
|
||||
queue = new ExtentTraverser<>(extent).findAndGet(SingleThreadQueueExtent.class);
|
||||
}
|
||||
if (queue == null) {
|
||||
LOGGER.warn("Could not find IQueueExtent instance for entity retrieval, OncePerChunkExtent will not work.");
|
||||
}
|
||||
}
|
||||
if (queue == null) {
|
||||
Set<Entity> entities = new HashSet<>(region != null ? source.getEntities(region) : source.getEntities());
|
||||
entities.removeIf(entity -> {
|
||||
EntityProperties properties = entity.getFacet(EntityProperties.class);
|
||||
return properties != null && !properties.isPasteable();
|
||||
});
|
||||
return entities;
|
||||
}
|
||||
LinkedBlockingQueue<Entity> entities = new LinkedBlockingQueue<>();
|
||||
Consumer<IChunkGet> task = (get) -> {
|
||||
if (region == null || region instanceof CuboidRegion cuboid && cuboid.chunkContainedBy(
|
||||
get.getX(),
|
||||
get.getZ(),
|
||||
get.getMinY(),
|
||||
get.getMaxY()
|
||||
)) {
|
||||
entities.addAll(get.getFullEntities());
|
||||
} else {
|
||||
get.getFullEntities().forEach(e -> {
|
||||
if (region.contains(e.getLocation().toBlockPoint())) {
|
||||
entities.add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Extent ext = extent instanceof AbstractDelegateExtent ex ? ex.getExtent() : extent;
|
||||
ExtentBatchProcessorHolder batchExtent = new ExtentTraverser<>(extent).findAndGet(ExtentBatchProcessorHolder.class);
|
||||
OncePerChunkExtent oncePer = new ExtentTraverser<>(extent).findAndGet(OncePerChunkExtent.class);
|
||||
if (batchExtent != null && oncePer == null) {
|
||||
oncePer = new ProcessorTraverser<>(batchExtent).find(OncePerChunkExtent.class);
|
||||
}
|
||||
if (oncePer != null) {
|
||||
oncePer.reset();
|
||||
oncePer.setTask(task);
|
||||
} else {
|
||||
oncePer = new OncePerChunkExtent(ext, queue, task);
|
||||
if (false && batchExtent != null) {
|
||||
batchExtent.getProcessor().join(oncePer);
|
||||
} else {
|
||||
new ExtentTraverser(extent).setNext(oncePer);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
@ -744,6 +744,26 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
return maxZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an entire chunk is contained by this region
|
||||
*
|
||||
* @param chunkX chunk x coord
|
||||
* @param chunkZ chunk z coord
|
||||
* @param chunkMinY The minimum Y level of the chunk
|
||||
* @param chunkMaxY The maximum Y level of the chunk
|
||||
* @return If the entire chunk is contained by this region
|
||||
* @since TODO
|
||||
*/
|
||||
public boolean chunkContainedBy(int chunkX, int chunkZ, int chunkMinY, int chunkMaxY) {
|
||||
int bx = chunkX << 4;
|
||||
int bz = chunkZ << 4;
|
||||
int tx = bx + 15;
|
||||
int tz = bz + 15;
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
return min.getY() <= chunkMinY && max.getY() >= chunkMaxY && min.getX() <= bx && max.getX() >= tx && min.getZ() <= bz && max.getZ() >= tz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(
|
||||
final IChunk chunk,
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren