2019-10-23 04:23:52 +00:00
|
|
|
package com.boydti.fawe.beta;
|
|
|
|
|
2020-01-03 21:51:23 +00:00
|
|
|
import com.boydti.fawe.Fawe;
|
2019-10-23 04:23:52 +00:00
|
|
|
import com.boydti.fawe.FaweCache;
|
2019-11-02 11:13:42 +00:00
|
|
|
import com.boydti.fawe.beta.implementation.processors.EmptyBatchProcessor;
|
|
|
|
import com.boydti.fawe.beta.implementation.processors.MultiBatchProcessor;
|
2019-10-23 04:23:52 +00:00
|
|
|
import com.sk89q.jnbt.CompoundTag;
|
|
|
|
import com.sk89q.worldedit.extent.Extent;
|
|
|
|
import com.sk89q.worldedit.math.BlockVector3;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.function.Function;
|
2020-01-15 00:44:09 +00:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
2019-10-23 04:23:52 +00:00
|
|
|
|
|
|
|
public interface IBatchProcessor {
|
|
|
|
/**
|
|
|
|
* Process a chunk that has been set
|
|
|
|
* @param chunk
|
|
|
|
* @param get
|
|
|
|
* @param set
|
|
|
|
* @return
|
|
|
|
*/
|
2019-10-23 14:35:04 +00:00
|
|
|
IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set);
|
|
|
|
|
|
|
|
default boolean processGet(int chunkX, int chunkZ) {
|
|
|
|
return true;
|
|
|
|
}
|
2019-10-23 04:23:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert this processor into an Extent based processor instead of a queue batch based on
|
|
|
|
* @param child
|
|
|
|
* @return
|
|
|
|
*/
|
2020-01-15 00:44:09 +00:00
|
|
|
@Nullable
|
2019-10-23 04:23:52 +00:00
|
|
|
Extent construct(Extent child);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Utility method to trim a chunk based on min and max Y
|
|
|
|
* @param set
|
|
|
|
* @param minY
|
|
|
|
* @param maxY
|
|
|
|
* @return false if chunk is empty of blocks
|
|
|
|
*/
|
|
|
|
default boolean trimY(IChunkSet set, int minY, int maxY) {
|
|
|
|
int minLayer = (minY - 1) >> 4;
|
|
|
|
for (int layer = 0; layer <= minLayer; layer++) {
|
|
|
|
if (set.hasSection(layer)) {
|
|
|
|
if (layer == minLayer) {
|
2019-11-07 10:28:17 +00:00
|
|
|
char[] arr = set.load(layer);
|
2019-11-02 12:12:21 +00:00
|
|
|
int index = (minY & 15) << 8;
|
2019-10-23 04:23:52 +00:00
|
|
|
for (int i = 0; i < index; i++) arr[i] = 0;
|
|
|
|
set.setBlocks(layer, arr);
|
|
|
|
} else {
|
|
|
|
set.setBlocks(layer, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int maxLayer = (maxY + 1) >> 4;
|
2020-01-29 20:01:38 +00:00
|
|
|
for (int layer = maxLayer; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) {
|
2019-10-23 04:23:52 +00:00
|
|
|
if (set.hasSection(layer)) {
|
|
|
|
if (layer == minLayer) {
|
2019-11-07 10:28:17 +00:00
|
|
|
char[] arr = set.load(layer);
|
2019-11-02 12:12:21 +00:00
|
|
|
int index = ((maxY + 1) & 15) << 8;
|
2019-10-23 04:23:52 +00:00
|
|
|
for (int i = index; i < arr.length; i++) arr[i] = 0;
|
|
|
|
set.setBlocks(layer, arr);
|
|
|
|
} else {
|
|
|
|
set.setBlocks(layer, null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-03 21:51:23 +00:00
|
|
|
try {
|
|
|
|
int layer = (minY - 15) >> 4;
|
|
|
|
while (layer < (maxY + 15) >> 4) {
|
2020-02-26 14:35:41 +00:00
|
|
|
if (layer > -1) {
|
2020-01-10 18:29:20 +00:00
|
|
|
if (set.hasSection(layer)) {
|
|
|
|
return true;
|
|
|
|
}
|
2020-01-03 21:51:23 +00:00
|
|
|
}
|
2020-02-26 14:35:41 +00:00
|
|
|
layer++;
|
2019-10-23 04:23:52 +00:00
|
|
|
}
|
2020-01-03 21:51:23 +00:00
|
|
|
} catch (ArrayIndexOutOfBoundsException exception) {
|
|
|
|
Fawe.imp().debug("minY = " + minY);
|
|
|
|
Fawe.imp().debug("layer = " + ((minY - 15) >> 4));
|
|
|
|
exception.printStackTrace();
|
2019-10-23 04:23:52 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Utility method to trim entity and blocks with a provided contains function
|
|
|
|
* @param set
|
|
|
|
* @param contains
|
|
|
|
* @return false if chunk is empty of NBT
|
|
|
|
*/
|
|
|
|
default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) {
|
|
|
|
Set<CompoundTag> ents = set.getEntities();
|
|
|
|
if (!ents.isEmpty()) {
|
2019-11-11 21:02:28 +00:00
|
|
|
ents.removeIf(ent -> !contains.apply(ent.getEntityPosition().toBlockPoint()));
|
2019-10-23 04:23:52 +00:00
|
|
|
}
|
|
|
|
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
|
|
|
|
if (!tiles.isEmpty()) {
|
2019-11-11 21:02:28 +00:00
|
|
|
tiles.entrySet().removeIf(blockVector3CompoundTagEntry -> !contains
|
|
|
|
.apply(blockVector3CompoundTagEntry.getKey()));
|
2019-10-23 04:23:52 +00:00
|
|
|
}
|
|
|
|
return !tiles.isEmpty() || !ents.isEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Join two processors and return the result
|
|
|
|
* @param other
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
default IBatchProcessor join(IBatchProcessor other) {
|
|
|
|
return MultiBatchProcessor.of(this, other);
|
|
|
|
}
|
|
|
|
|
2019-11-16 00:20:14 +00:00
|
|
|
default void flush() {}
|
|
|
|
|
2019-10-23 04:23:52 +00:00
|
|
|
/**
|
|
|
|
* Return a new processor after removing all are instances of a specified class
|
|
|
|
* @param clazz
|
|
|
|
* @param <T>
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
default <T extends IBatchProcessor> IBatchProcessor remove(Class<T> clazz) {
|
|
|
|
if (clazz.isInstance(this)) {
|
|
|
|
return EmptyBatchProcessor.INSTANCE;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
}
|