geforkt von Mirrors/FastAsyncWorldEdit
Ursprung
bfcc6184ad
Commit
238c56a3c6
@ -7,7 +7,7 @@ New contributions must be licensed under:
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -180,7 +180,7 @@ WorldEdit as a whole is licensed under:
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import org.gradle.api.Project
|
||||
|
||||
object Versions {
|
||||
const val TEXT = "3.0.3"
|
||||
const val TEXT_EXTRAS = "3.0.3"
|
||||
const val TEXT = "3.0.4"
|
||||
const val TEXT_EXTRAS = "3.0.5"
|
||||
const val PISTON = "0.5.5"
|
||||
const val AUTO_VALUE = "1.7"
|
||||
const val JUNIT = "5.6.1"
|
||||
|
@ -73,6 +73,7 @@
|
||||
<allow pkg="org.spongepowered.api" />
|
||||
<allow pkg="com.mojang.brigadier" />
|
||||
<allow pkg="com.mojang.datafixers" />
|
||||
<allow pkg="org.apache.commons" />
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="fabric">
|
||||
|
@ -128,6 +128,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
public int getSkyLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (skyLight[layer] == null) {
|
||||
//getDataLayerData
|
||||
skyLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.SKY).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
@ -138,6 +139,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
int layer = y >> 4;
|
||||
if (blockLight[layer] == null) {
|
||||
//getDataLayerData
|
||||
blockLight[layer] = world.getChunkProvider().getLightEngine().a(EnumSkyBlock.BLOCK).a(SectionPosition.a(nmsChunk.getPos(), layer));
|
||||
}
|
||||
long l = BlockPosition.a(x, y, z);
|
||||
|
@ -20,11 +20,6 @@
|
||||
package com.sk89q.bukkit.util;
|
||||
|
||||
import com.sk89q.util.ReflectionUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -33,6 +28,12 @@ import org.bukkit.command.PluginIdentifiableCommand;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CommandRegistration {
|
||||
|
||||
static {
|
||||
@ -61,6 +62,7 @@ public class CommandRegistration {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean register(List<CommandInfo> registered) {
|
||||
CommandMap commandMap = getCommandMap();
|
||||
if (registered == null || commandMap == null) {
|
||||
@ -82,6 +84,7 @@ public class CommandRegistration {
|
||||
if (fallbackCommands != null) {
|
||||
return fallbackCommands;
|
||||
}
|
||||
|
||||
CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
|
||||
if (commandMap == null) {
|
||||
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName() +
|
||||
|
@ -31,7 +31,7 @@ import java.nio.charset.StandardCharsets;
|
||||
*/
|
||||
public class CUIChannelListener implements PluginMessageListener {
|
||||
|
||||
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
|
||||
public static final Charset UTF_8_CHARSET = StandardCharsets.UTF_8;
|
||||
private final WorldEditPlugin plugin;
|
||||
|
||||
public CUIChannelListener(WorldEditPlugin plugin) {
|
||||
|
@ -117,27 +117,6 @@ public class FaweAPI {
|
||||
// return parser != null;
|
||||
// }
|
||||
|
||||
public static <T> T getParser(Class<T> parserClass) {
|
||||
try {
|
||||
Field field = AbstractFactory.class.getDeclaredField("parsers");
|
||||
field.setAccessible(true);
|
||||
ArrayList<InputParser> parsers = new ArrayList<>();
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getMaskFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getBlockFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getItemFactory()));
|
||||
parsers.addAll((List<InputParser>) field.get(WorldEdit.getInstance().getPatternFactory()));
|
||||
for (InputParser parser : parsers) {
|
||||
if (parserClass.isAssignableFrom(parser.getClass())) {
|
||||
return (T) parser;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* You can either use a IQueueExtent or an EditSession to change blocks<br>
|
||||
* - The IQueueExtent skips a bit of overhead so it's marginally faster<br>
|
||||
|
@ -50,7 +50,7 @@ public class AsyncPreloader implements Preloader, Runnable {
|
||||
MutablePair<World, Set<BlockVector2>> existing = cancelAndGet(player);
|
||||
try {
|
||||
Region region = session.getSelection(world);
|
||||
if (!(region instanceof CuboidRegion) || region.getArea() > 50466816) {
|
||||
if (!(region instanceof CuboidRegion) || region.getVolume() > 50466816) {
|
||||
// TOO LARGE or NOT CUBOID
|
||||
return;
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
for (int y = 255; y > 0; y--) {
|
||||
for (RelightSkyEntry chunk : chunks) { // Propogate skylight
|
||||
for (RelightSkyEntry chunk : chunks) { // Propagate skylight
|
||||
int layer = y >> 4;
|
||||
byte[] mask = chunk.mask;
|
||||
if ((y & 15) == 15 && chunk.fix[layer] != SkipReason.NONE) {
|
||||
@ -596,7 +596,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
|
||||
private class RelightSkyEntry implements Comparable {
|
||||
private class RelightSkyEntry implements Comparable<RelightSkyEntry> {
|
||||
public final int x;
|
||||
public final int z;
|
||||
public final byte[] mask;
|
||||
@ -625,18 +625,17 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
RelightSkyEntry other = (RelightSkyEntry) o;
|
||||
if (other.x < x) {
|
||||
public int compareTo(RelightSkyEntry o) {
|
||||
if (o.x < x) {
|
||||
return 1;
|
||||
}
|
||||
if (other.x > x) {
|
||||
if (o.x > x) {
|
||||
return -1;
|
||||
}
|
||||
if (other.z < z) {
|
||||
if (o.z < z) {
|
||||
return 1;
|
||||
}
|
||||
if (other.z > z) {
|
||||
if (o.z > z) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -52,7 +52,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return getExtent().getEntities(region);
|
||||
} catch (FaweException e) {
|
||||
@ -223,8 +223,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void addCaves(Region region) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().addCaves(region);
|
||||
} catch (FaweException e) {
|
||||
@ -236,8 +236,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void generate(Region region, GenBase gen) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().generate(region, gen);
|
||||
} catch (FaweException e) {
|
||||
@ -249,8 +249,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void addSchems(Region region, Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().addSchems(region, mask, clipboards, rarity, rotate);
|
||||
} catch (FaweException e) {
|
||||
@ -262,8 +262,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().spawnResource(region, gen, rarity, frequency);
|
||||
} catch (FaweException e) {
|
||||
@ -275,8 +275,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().addOre(region, mask, material, size, frequency, rarity, minY, maxY);
|
||||
} catch (FaweException e) {
|
||||
@ -288,8 +288,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
getExtent().addOres(region, mask);
|
||||
} catch (FaweException e) {
|
||||
@ -301,7 +301,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockType>> getBlockDistribution(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return getExtent().getBlockDistribution(region);
|
||||
} catch (FaweException e) {
|
||||
@ -314,7 +314,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public List<Countable<BlockState>> getBlockDistributionWithData(Region region) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return getExtent().getBlockDistributionWithData(region);
|
||||
} catch (FaweException e) {
|
||||
@ -327,7 +327,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return getExtent().countBlocks(region, searchBlocks);
|
||||
} catch (FaweException e) {
|
||||
@ -340,7 +340,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int countBlocks(Region region, Mask searchMask) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
try {
|
||||
return getExtent().countBlocks(region, searchMask);
|
||||
} catch (FaweException e) {
|
||||
@ -353,7 +353,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().setBlocks(region, block);
|
||||
} catch (FaweException e) {
|
||||
@ -366,7 +366,7 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().setBlocks(region, pattern);
|
||||
} catch (FaweException e) {
|
||||
@ -379,8 +379,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().replaceBlocks(region, filter, replacement);
|
||||
} catch (FaweException e) {
|
||||
@ -393,8 +393,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().replaceBlocks(region, filter, pattern);
|
||||
} catch (FaweException e) {
|
||||
@ -407,8 +407,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().replaceBlocks(region, mask, pattern);
|
||||
} catch (FaweException e) {
|
||||
@ -421,8 +421,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().center(region, pattern);
|
||||
} catch (FaweException e) {
|
||||
@ -448,8 +448,8 @@ public class LimitExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public <T extends Filter> T apply(Region region, T filter, boolean full) {
|
||||
limit.THROW_MAX_CHECKS(region.getArea());
|
||||
limit.THROW_MAX_CHANGES(region.getArea());
|
||||
limit.THROW_MAX_CHECKS(region.getVolume());
|
||||
limit.THROW_MAX_CHANGES(region.getVolume());
|
||||
try {
|
||||
return getExtent().apply(region, filter, full);
|
||||
} catch (FaweException e) {
|
||||
|
@ -151,10 +151,6 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
||||
return forkJoinPoolPrimary.submit(call);
|
||||
}
|
||||
|
||||
public <T> Future<T> sync(Runnable run, T value) {
|
||||
return sync(run, value, syncTasks);
|
||||
}
|
||||
|
||||
public <T> Future<T> sync(Runnable run) {
|
||||
return sync(run, syncTasks);
|
||||
}
|
||||
|
@ -1,22 +1,3 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.boydti.fawe.function.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
@ -1,22 +1,3 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.boydti.fawe.function.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
@ -9,6 +9,10 @@ public class XAxisMask extends AbstractMask implements ResettableMask {
|
||||
|
||||
private transient int layer = -1;
|
||||
|
||||
public XAxisMask(Extent extent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Extent extent, BlockVector3 vector) {
|
||||
if (layer == -1) {
|
||||
|
@ -9,6 +9,9 @@ public class YAxisMask extends AbstractMask implements ResettableMask {
|
||||
|
||||
private transient int layer = -1;
|
||||
|
||||
public YAxisMask(Extent extent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Extent extent, BlockVector3 vector) {
|
||||
if (layer == -1) {
|
||||
|
@ -9,6 +9,9 @@ public class ZAxisMask extends AbstractMask implements ResettableMask {
|
||||
|
||||
private transient int layer = -1;
|
||||
|
||||
public ZAxisMask(Extent extent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Extent extent, BlockVector3 vector) {
|
||||
if (layer == -1) {
|
||||
|
@ -162,6 +162,9 @@ public class FaweLimit {
|
||||
public void THROW_MAX_CHANGES(int amt) {
|
||||
if ((MAX_CHANGES -= amt) <= 0) throw FaweCache.MAX_CHANGES;
|
||||
}
|
||||
public void THROW_MAX_CHANGES(long amt) {
|
||||
if ((MAX_CHANGES -= amt) <= 0) throw FaweCache.MAX_CHANGES;
|
||||
}
|
||||
|
||||
public void THROW_MAX_FAILS(int amt) {
|
||||
if ((MAX_FAILS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
|
||||
@ -171,6 +174,10 @@ public class FaweLimit {
|
||||
if ((MAX_CHECKS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
|
||||
public void THROW_MAX_CHECKS(long amt) {
|
||||
if ((MAX_CHECKS -= amt) <= 0) throw FaweCache.MAX_CHECKS;
|
||||
}
|
||||
|
||||
public void THROW_MAX_ITERATIONS(int amt) {
|
||||
if ((MAX_ITERATIONS -= amt) <= 0) throw FaweCache.MAX_ITERATIONS;
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package com.boydti.fawe.object;
|
||||
|
||||
public final class IntTriple {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
|
||||
public IntTriple(int x, int y, int z) {
|
||||
this.x = x;
|
||||
|
@ -1,8 +0,0 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface Lazy<T> extends Supplier<T> {
|
||||
Supplier<T> init();
|
||||
public default T get() { return init().get(); }
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public abstract class RunnableVal2<T, U> implements Runnable, BiConsumer<T, U> {
|
||||
public T value1;
|
||||
public U value2;
|
||||
|
||||
public RunnableVal2() {
|
||||
}
|
||||
|
||||
public RunnableVal2(T value1, U value2) {
|
||||
this.value1 = value1;
|
||||
this.value2 = value2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
run(this.value1, this.value2);
|
||||
}
|
||||
|
||||
public abstract void run(T value1, U value2);
|
||||
|
||||
public RunnableVal2<T, U> runAndGet(T value1, U value2) {
|
||||
run(value1, value2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t, U u) {
|
||||
run(t, u);
|
||||
}
|
||||
}
|
@ -93,7 +93,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
||||
}
|
||||
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMapLoc.entrySet()) {
|
||||
IntTriple key = entry.getKey();
|
||||
setTile(getIndex(key.x, key.y, key.z), entry.getValue());
|
||||
setTile(getIndex(key.getX(), key.getY(), key.getZ()), entry.getValue());
|
||||
}
|
||||
nbtMapLoc.clear();
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
||||
nbt = null;
|
||||
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMap.entrySet()) {
|
||||
IntTriple key = entry.getKey();
|
||||
int index = getIndex(key.x, key.y, key.z);
|
||||
int index = getIndex(key.getX(), key.getY(), key.getZ());
|
||||
if (index == i) {
|
||||
nbt = entry.getValue();
|
||||
break;
|
||||
|
@ -200,7 +200,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
||||
nbt = null;
|
||||
for (Map.Entry<IntTriple, CompoundTag> entry : nbtMap.entrySet()) {
|
||||
IntTriple trio = entry.getKey();
|
||||
int index = getIndex(trio.x, trio.y, trio.z);
|
||||
int index = getIndex(trio.getX(), trio.getY(), trio.getZ());
|
||||
if (index == i) {
|
||||
nbt = entry.getValue();
|
||||
break;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.function.mask.AbstractMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -14,7 +15,7 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask {
|
||||
private final CachedMask mask;
|
||||
private final MutableBlockVector3 mutable;
|
||||
|
||||
public AdjacentAnyMask(Mask mask) {
|
||||
public AdjacentAnyMask(AbstractExtentMask mask) {
|
||||
this.mask = CachedMask.cache(mask);
|
||||
mutable = new MutableBlockVector3();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.mask;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -11,7 +12,7 @@ public class SurfaceMask extends AdjacentAnyMask {
|
||||
super(getMask(extent));
|
||||
}
|
||||
|
||||
public static Mask getMask(Extent extent) {
|
||||
public static AbstractExtentMask getMask(Extent extent) {
|
||||
return new BlockMaskBuilder()
|
||||
.addTypes(BlockTypes.AIR, BlockTypes.CAVE_AIR, BlockTypes.VOID_AIR)
|
||||
.addAll(b -> !b.getMaterial().isMovementBlocker())
|
||||
|
@ -87,14 +87,12 @@ public class FuzzyRegionSelector extends PassthroughExtent implements RegionSele
|
||||
|
||||
@Override
|
||||
public void explainPrimarySelection(Actor actor, LocalSession session, BlockVector3 position) {
|
||||
int size = this.region.getArea();
|
||||
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos1", position, "(" + region.getArea() + ")"));
|
||||
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos1", position, "(" + region.getVolume() + ")"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void explainSecondarySelection(Actor actor, LocalSession session, BlockVector3 position) {
|
||||
int size = this.region.getArea();
|
||||
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos2", position, "(" + region.getArea() + ")"));
|
||||
player.print(Caption.of("fawe.worldedit.selector.selector.fuzzy.pos2", position, "(" + region.getVolume() + ")"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,8 +99,8 @@ public abstract class DFSVisitor implements Operation {
|
||||
// mutable2.mutY(from.getY() + direction.y);
|
||||
// mutable2.mutZ(from.getZ() + direction.z);
|
||||
BlockVector3 bv2 = BlockVector3
|
||||
.at(from.getX() + direction.x, from.getY() + direction.y,
|
||||
from.getZ() + direction.z);
|
||||
.at(from.getX() + direction.getX(), from.getY() + direction.getY(),
|
||||
from.getZ() + direction.getZ());
|
||||
if (isVisitable(bv, bv2)) {
|
||||
Node adjacent = new Node(bv2.getBlockX(), bv2.getBlockY(), bv2.getBlockZ());
|
||||
if (!adjacent.equals(current.from)) {
|
||||
|
@ -5,29 +5,17 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.beta.IBatchProcessor;
|
||||
import com.boydti.fawe.beta.IQueueChunk;
|
||||
import com.boydti.fawe.beta.IQueueExtent;
|
||||
import com.boydti.fawe.beta.implementation.lighting.NMSRelighter;
|
||||
import com.boydti.fawe.beta.implementation.lighting.NullRelighter;
|
||||
import com.boydti.fawe.beta.implementation.lighting.Relighter;
|
||||
import com.boydti.fawe.beta.implementation.processors.LimitProcessor;
|
||||
import com.boydti.fawe.beta.implementation.queue.ParallelQueueExtent;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.HistoryExtent;
|
||||
import com.boydti.fawe.object.NullChangeSet;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RelightMode;
|
||||
import com.boydti.fawe.object.*;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.changeset.AbstractChangeSet;
|
||||
import com.boydti.fawe.object.changeset.BlockBagChangeSet;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.changeset.MemoryOptimizedHistory;
|
||||
import com.boydti.fawe.object.extent.FaweRegionExtent;
|
||||
import com.boydti.fawe.object.extent.MultiRegionExtent;
|
||||
import com.boydti.fawe.object.extent.NullExtent;
|
||||
import com.boydti.fawe.object.extent.SingleRegionExtent;
|
||||
import com.boydti.fawe.object.extent.SlowExtent;
|
||||
import com.boydti.fawe.object.extent.StripNBTExtent;
|
||||
import com.boydti.fawe.object.extent.*;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
|
@ -4,6 +4,7 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExtentTraverser<T extends Extent> {
|
||||
@ -48,21 +49,8 @@ public class ExtentTraverser<T extends Extent> {
|
||||
return last;
|
||||
}
|
||||
|
||||
public boolean insert(T extent) {
|
||||
try {
|
||||
Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||
field.setAccessible(true);
|
||||
field.set(extent, field.get(root));
|
||||
field.set(root, extent);
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public <U> U findAndGet(Class<U> clazz) {
|
||||
ExtentTraverser<Extent> traverser = find( clazz);
|
||||
ExtentTraverser<Extent> traverser = find(clazz);
|
||||
return (traverser != null) ? (U) traverser.get() : null;
|
||||
}
|
||||
|
||||
|
@ -1,92 +1,51 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import static java.lang.System.arraycopy;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.changeset.FaweStreamChangeSet;
|
||||
import com.boydti.fawe.object.io.AbstractDelegateOutputStream;
|
||||
import com.github.luben.zstd.ZstdInputStream;
|
||||
import com.github.luben.zstd.ZstdOutputStream;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.awt.Graphics2D;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
|
||||
import net.jpountz.lz4.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.*;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import java.util.zip.*;
|
||||
|
||||
import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import net.jpountz.lz4.LZ4Compressor;
|
||||
import net.jpountz.lz4.LZ4Factory;
|
||||
import net.jpountz.lz4.LZ4FastDecompressor;
|
||||
import net.jpountz.lz4.LZ4InputStream;
|
||||
import net.jpountz.lz4.LZ4Utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import static java.lang.System.arraycopy;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
public class MainUtil {
|
||||
|
||||
@ -112,22 +71,22 @@ public class MainUtil {
|
||||
|
||||
public static long getTotalSize(Path path) {
|
||||
final AtomicLong size = new AtomicLong(0);
|
||||
traverse(path, new RunnableVal2<Path, BasicFileAttributes>() {
|
||||
traverse(path, new RunnableVal<BasicFileAttributes>() {
|
||||
@Override
|
||||
public void run(Path path, BasicFileAttributes attrs) {
|
||||
public void run(BasicFileAttributes attrs) {
|
||||
size.addAndGet(attrs.size());
|
||||
}
|
||||
});
|
||||
return size.get();
|
||||
}
|
||||
|
||||
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
|
||||
public static void traverse(Path path, final Consumer<BasicFileAttributes> onEach) {
|
||||
try {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult
|
||||
visitFile(Path file, BasicFileAttributes attrs) {
|
||||
onEach.accept(file, attrs);
|
||||
onEach.accept(attrs);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@ -169,7 +128,7 @@ public class MainUtil {
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static void forEachFile(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach, Comparator<File> comparator) {
|
||||
public static void forEachFile(Path path, final RunnableVal<BasicFileAttributes> onEach, Comparator<File> comparator) {
|
||||
File dir = path.toFile();
|
||||
if (!dir.exists()) return;
|
||||
File[] files = path.toFile().listFiles();
|
||||
@ -178,7 +137,7 @@ public class MainUtil {
|
||||
Path filePath = file.toPath();
|
||||
try {
|
||||
BasicFileAttributes attr = Files.readAttributes(filePath, BasicFileAttributes.class);
|
||||
onEach.run(file.toPath(), attr);
|
||||
onEach.run(attr);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import com.boydti.fawe.object.mask.ResettableMask;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
@ -38,6 +40,18 @@ public class MaskTraverser {
|
||||
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
if (mask instanceof MaskIntersection) {
|
||||
MaskIntersection mask1 = (MaskIntersection) mask;
|
||||
try {
|
||||
Field field = mask1.getClass().getDeclaredField("masks");
|
||||
field.setAccessible(true);
|
||||
Collection<Mask> masks = (Collection<Mask>) field.get(mask);
|
||||
for (Mask next : masks) {
|
||||
reset(next, newExtent);
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Field field = current.getDeclaredField("mask");
|
||||
field.setAccessible(true);
|
||||
|
@ -1,27 +0,0 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class RegionCacheUtil {
|
||||
public RegionCacheUtil() {
|
||||
|
||||
}
|
||||
|
||||
public void cache(Region region) {
|
||||
Iterator<BlockVector3> iter = region.iterator();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
TaskManager.IMP.async(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -33,15 +33,9 @@ public class WEManager {
|
||||
|
||||
public void cancelEditSafe(AbstractDelegateExtent parent, FaweException reason) throws FaweException {
|
||||
log.warn("CancelEditSafe was hit. Please ignore this message.");
|
||||
try {
|
||||
final Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||
field.setAccessible(true);
|
||||
Extent currentExtent = parent.getExtent();
|
||||
if (!(currentExtent instanceof NullExtent)) {
|
||||
field.set(parent, new NullExtent((Extent) field.get(parent), reason));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
parent.extent = new NullExtent(parent.extent, reason);
|
||||
}
|
||||
throw reason;
|
||||
}
|
||||
|
@ -1102,7 +1102,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
* @param radius the radius of the spherical area to fill
|
||||
* @param depth the maximum depth, starting from the origin
|
||||
* @param direction the direction to fill
|
||||
* @return number of blocks affected
|
||||
* @return the number of blocks affected
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int fillDirection(final BlockVector3 origin, final Pattern pattern, final double radius, final int depth, BlockVector3 direction) throws MaxChangedBlocksException {
|
||||
@ -1181,7 +1181,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
visitor.visit(origin);
|
||||
|
||||
// Execute
|
||||
Operations.completeBlindly(visitor);
|
||||
Operations.completeLegacy(visitor);
|
||||
|
||||
return this.changes = visitor.getAffected();
|
||||
}
|
||||
@ -2185,10 +2185,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
*
|
||||
* @param position a position
|
||||
* @param radius a radius
|
||||
* @param onlyNormalDirt only affect normal dirt (data value 0)
|
||||
* @param onlyNormalDirt only affect normal dirt (all default properties)
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
@Deprecated
|
||||
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
|
||||
throws MaxChangedBlocksException {
|
||||
final double radiusSq = radius * radius;
|
||||
@ -2257,7 +2258,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
GroundFunction ground = new GroundFunction(new ExistingBlockMask(this), generator);
|
||||
LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground);
|
||||
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
|
||||
Operations.completeBlindly(visitor);
|
||||
Operations.completeLegacy(visitor);
|
||||
return this.changes = ground.getAffected();
|
||||
}
|
||||
|
||||
@ -2403,11 +2404,42 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deforms the region by a given expression. A deform provides a block's x, y, and z coordinates (possibly scaled)
|
||||
* to an expression, and then sets the block to the block given by the resulting values of the variables, if they
|
||||
* have changed.
|
||||
*
|
||||
* @param region the region to deform
|
||||
* @param zero the origin of the coordinate system
|
||||
* @param unit the scale of the coordinate system
|
||||
* @param expressionString the expression to evaluate for each block
|
||||
*
|
||||
* @return number of blocks changed
|
||||
*
|
||||
* @throws ExpressionException thrown on invalid expression input
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString)
|
||||
throws ExpressionException, MaxChangedBlocksException {
|
||||
return deformRegion(region, zero, unit, expressionString, WorldEdit.getInstance().getConfiguration().calculationTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deforms the region by a given expression. A deform provides a block's x, y, and z coordinates (possibly scaled)
|
||||
* to an expression, and then sets the block to the block given by the resulting values of the variables, if they
|
||||
* have changed.
|
||||
*
|
||||
* @param region the region to deform
|
||||
* @param zero the origin of the coordinate system
|
||||
* @param unit the scale of the coordinate system
|
||||
* @param expressionString the expression to evaluate for each block
|
||||
* @param timeout maximum time for the expression to evaluate for each block. -1 for unlimited.
|
||||
*
|
||||
* @return number of blocks changed
|
||||
*
|
||||
* @throws ExpressionException thrown on invalid expression input
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int deformRegion(final Region region, final Vector3 zero, final Vector3 unit, final String expressionString,
|
||||
final int timeout) throws ExpressionException, MaxChangedBlocksException {
|
||||
final Expression expression = Expression.compile(expressionString, "x", "y", "z");
|
||||
@ -2425,7 +2457,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
final Vector3 zero2 = zero.add(0.5, 0.5, 0.5);
|
||||
|
||||
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
||||
private final MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
|
||||
@Override
|
||||
public boolean apply(BlockVector3 position) throws WorldEditException {
|
||||
|
@ -176,7 +176,7 @@ public class ClipboardCommands {
|
||||
|
||||
lazyClipboard.setOrigin(session.getPlacementPosition(actor));
|
||||
session.setClipboard(new ClipboardHolder(lazyClipboard));
|
||||
actor.print(Caption.of("fawe.worldedit.copy.command.copy" , region.getArea()));
|
||||
actor.print(Caption.of("fawe.worldedit.copy.command.copy" , region.getVolume()));
|
||||
}
|
||||
|
||||
// @Command(
|
||||
|
@ -104,14 +104,14 @@ public class ExpandCommands {
|
||||
private static void expandVert(LocalSession session, Actor actor, World world) throws IncompleteRegionException {
|
||||
Region region = session.getSelection(world);
|
||||
try {
|
||||
int oldSize = region.getArea();
|
||||
long oldSize = region.getVolume();
|
||||
region.expand(
|
||||
BlockVector3.at(0, (world.getMaxY() + 1), 0),
|
||||
BlockVector3.at(0, -(world.getMaxY() + 1), 0));
|
||||
session.getRegionSelector(world).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
long newSize = region.getVolume();
|
||||
session.getRegionSelector(world).explainRegionAdjust(actor, session);
|
||||
int changeSize = newSize - oldSize;
|
||||
long changeSize = newSize - oldSize;
|
||||
actor.printInfo(
|
||||
TranslatableComponent.of("worldedit.expand.expanded.vert", TextComponent.of(changeSize))
|
||||
);
|
||||
@ -134,7 +134,7 @@ public class ExpandCommands {
|
||||
@MultiDirection
|
||||
List<BlockVector3> direction) throws WorldEditException {
|
||||
Region region = session.getSelection(world);
|
||||
int oldSize = region.getArea();
|
||||
long oldSize = region.getVolume();
|
||||
|
||||
if (reverseAmount == 0) {
|
||||
for (BlockVector3 dir : direction) {
|
||||
@ -147,11 +147,11 @@ public class ExpandCommands {
|
||||
}
|
||||
|
||||
session.getRegionSelector(world).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
long newSize = region.getVolume();
|
||||
|
||||
session.getRegionSelector(world).explainRegionAdjust(actor, session);
|
||||
|
||||
int changeSize = newSize - oldSize;
|
||||
long changeSize = newSize - oldSize;
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.expand.expanded", TextComponent.of(changeSize)));
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,7 @@
|
||||
//import com.boydti.fawe.object.mask.BiomeMask;
|
||||
//import com.boydti.fawe.object.mask.BlockLightMask;
|
||||
//import com.boydti.fawe.object.mask.BrightnessMask;
|
||||
//import com.boydti.fawe.object.mask.DataMask;
|
||||
//import com.boydti.fawe.object.mask.ExtremaMask;
|
||||
//import com.boydti.fawe.object.mask.IdDataMask;
|
||||
//import com.boydti.fawe.object.mask.IdMask;
|
||||
//import com.boydti.fawe.object.mask.LightMask;
|
||||
//import com.boydti.fawe.object.mask.OpacityMask;
|
||||
//import com.boydti.fawe.object.mask.ROCAngleMask;
|
||||
@ -171,22 +168,6 @@
|
||||
// }
|
||||
//
|
||||
// @Command(
|
||||
// name = "#id",
|
||||
// desc = "Restrict to initial id"
|
||||
// )
|
||||
// public Mask id(Extent extent) {
|
||||
// return new IdMask(extent);
|
||||
// }
|
||||
//
|
||||
// @Command(
|
||||
// name = "#data",
|
||||
// desc = "Restrict to initial data"
|
||||
// )
|
||||
// public Mask data(Extent extent) {
|
||||
// return new DataMask(extent);
|
||||
// }
|
||||
//
|
||||
// @Command(
|
||||
// name = "#iddata",
|
||||
// desc = "Restrict to initial block id and data"
|
||||
// )
|
||||
|
@ -205,7 +205,7 @@ public class RegionCommands {
|
||||
desc = "Set block lighting in a selection"
|
||||
)
|
||||
@CommandPermissions("worldedit.light.set")
|
||||
public void setlighting(Player player, EditSession editSession, @Selection Region region, @Range(from = 0, to = 15) int value) {
|
||||
public void setlighting(Player player, EditSession editSession, @Selection Region region) {
|
||||
player.print(TextComponent.of("Temporarily not working"));
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class RegionCommands {
|
||||
desc = "Set sky lighting in a selection"
|
||||
)
|
||||
@CommandPermissions("worldedit.light.set")
|
||||
public void setskylighting(Player player, @Selection Region region, @Range(from = 0, to= 15) int value) {
|
||||
public void setskylighting(Player player, @Selection Region region) {
|
||||
player.printInfo(TextComponent.of("Temporarily not working"));
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ public class SelectionCommands {
|
||||
List<BlockVector3> direction) throws WorldEditException {
|
||||
try {
|
||||
Region region = session.getSelection(world);
|
||||
int oldSize = region.getArea();
|
||||
long oldSize = region.getVolume();
|
||||
if (reverseAmount == 0) {
|
||||
for (BlockVector3 dir : direction) {
|
||||
region.contract(dir.multiply(amount));
|
||||
@ -350,7 +350,7 @@ public class SelectionCommands {
|
||||
}
|
||||
}
|
||||
session.getRegionSelector(world).learnChanges();
|
||||
int newSize = region.getArea();
|
||||
long newSize = region.getVolume();
|
||||
|
||||
session.getRegionSelector(world).explainRegionAdjust(actor, session);
|
||||
|
||||
@ -501,7 +501,7 @@ public class SelectionCommands {
|
||||
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.size.size", TextComponent.of(size.toString())));
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.size.distance", TextComponent.of(region.getMaximumPoint().distance(region.getMinimumPoint()))));
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.size.blocks", TextComponent.of(region.getArea())));
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.size.blocks", TextComponent.of(region.getVolume())));
|
||||
}
|
||||
|
||||
@Command(
|
||||
|
@ -20,22 +20,7 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.AirMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.BiomeMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.BlockCategoryMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.BlockStateMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.BlocksMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.ExistingMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.ExpressionMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.FalseMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.LazyRegionMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.LiquidMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.NegateMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.TrueMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.parser.mask.*;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
@ -81,6 +66,9 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
||||
register(new TrueMaskParser(worldEdit));
|
||||
register(new AirMaskParser(worldEdit));
|
||||
register(new LiquidMaskParser(worldEdit));
|
||||
register(new XAxisMaskParser(worldEdit));
|
||||
register(new YAxisMaskParser(worldEdit));
|
||||
register(new ZAxisMaskParser(worldEdit));
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,3 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.boydti.fawe.function.mask.AirMask;
|
||||
|
@ -1,22 +1,3 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.boydti.fawe.function.mask.LiquidMask;
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.boydti.fawe.function.mask.XAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class XAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#xaxis");
|
||||
|
||||
public XAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new XAxisMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.boydti.fawe.function.mask.XAxisMask;
|
||||
import com.boydti.fawe.function.mask.YAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class YAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#yaxis");
|
||||
|
||||
public YAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new YAxisMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.boydti.fawe.function.mask.XAxisMask;
|
||||
import com.boydti.fawe.function.mask.ZAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ZAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#zaxis");
|
||||
|
||||
public ZAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new ZAxisMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.boydti.fawe.config.Caption;
|
||||
import com.boydti.fawe.object.task.AsyncNotifyQueue;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
|
||||
@ -701,10 +700,10 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
* @return
|
||||
*/
|
||||
public Region getLargestRegion() {
|
||||
int area = 0;
|
||||
long area = 0;
|
||||
Region max = null;
|
||||
for (Region region : this.getCurrentRegions()) {
|
||||
final int tmp = region.getArea();
|
||||
final long tmp = region.getVolume();
|
||||
if (tmp > area) {
|
||||
area = tmp;
|
||||
max = region;
|
||||
|
@ -59,7 +59,8 @@ public class AbstractDelegateExtent implements Extent {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractDelegateExtent.class);
|
||||
|
||||
private final Extent extent;
|
||||
//Not safe for public usage
|
||||
public Extent extent;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
|
@ -27,8 +27,9 @@ public class SelectionPoint2DEvent implements CUIEvent {
|
||||
protected final int id;
|
||||
protected final int blockX;
|
||||
protected final int blockZ;
|
||||
protected final int area;
|
||||
protected final long area;
|
||||
|
||||
@Deprecated
|
||||
public SelectionPoint2DEvent(int id, BlockVector2 pos, int area) {
|
||||
this.id = id;
|
||||
this.blockX = pos.getX();
|
||||
@ -36,6 +37,7 @@ public class SelectionPoint2DEvent implements CUIEvent {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public SelectionPoint2DEvent(int id, BlockVector3 pos, int area) {
|
||||
this.id = id;
|
||||
this.blockX = pos.getX();
|
||||
@ -43,6 +45,20 @@ public class SelectionPoint2DEvent implements CUIEvent {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public SelectionPoint2DEvent(int id, BlockVector2 pos, long area) {
|
||||
this.id = id;
|
||||
this.blockX = pos.getX();
|
||||
this.blockZ = pos.getZ();
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public SelectionPoint2DEvent(int id, BlockVector3 pos, long area) {
|
||||
this.id = id;
|
||||
this.blockX = pos.getX();
|
||||
this.blockZ = pos.getZ();
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeId() {
|
||||
return "p2";
|
||||
|
@ -25,14 +25,21 @@ public class SelectionPointEvent implements CUIEvent {
|
||||
|
||||
protected final int id;
|
||||
protected final BlockVector3 pos;
|
||||
protected final int area;
|
||||
protected final long area;
|
||||
|
||||
@Deprecated
|
||||
public SelectionPointEvent(int id, BlockVector3 pos, int area) {
|
||||
this.id = id;
|
||||
this.pos = pos;
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public SelectionPointEvent(int id, BlockVector3 pos, long area) {
|
||||
this.id = id;
|
||||
this.pos = pos;
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeId() {
|
||||
return "p";
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.regions;
|
||||
|
||||
import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
@ -44,7 +45,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return getArea();
|
||||
return com.google.common.primitives.Ints.saturatedCast(getVolume());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,19 +107,14 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of blocks in the region.
|
||||
*
|
||||
* @return number of blocks
|
||||
*/
|
||||
@Override
|
||||
public int getArea() {
|
||||
public long getVolume() {
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
|
||||
return (max.getX() - min.getX() + 1) *
|
||||
(max.getY() - min.getY() + 1) *
|
||||
(max.getZ() - min.getZ() + 1);
|
||||
return (max.getX() - min.getX() + 1L) *
|
||||
(max.getY() - min.getY() + 1L) *
|
||||
(max.getZ() - min.getZ() + 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,7 +214,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
|
||||
int result = worldHash ^ (worldHash >>> 32);
|
||||
result = 31 * result + this.getMinimumPoint().hashCode();
|
||||
result = 31 * result + this.getMaximumPoint().hashCode();
|
||||
result = 31 * result + this.getArea();
|
||||
result = (int) (31 * result + this.getVolume());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -239,7 +235,7 @@ public abstract class AbstractRegion extends AbstractSet<BlockVector3> implement
|
||||
if(this.getWorld().equals(region.getWorld())
|
||||
&& this.getMinimumPoint().equals(region.getMinimumPoint())
|
||||
&& this.getMaximumPoint().equals(region.getMaximumPoint())
|
||||
&& this.getArea() == region.getArea()){
|
||||
&& this.getVolume() == region.getVolume()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -35,6 +35,9 @@ import com.sk89q.worldedit.math.geom.Polygons;
|
||||
import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator;
|
||||
import com.sk89q.worldedit.regions.iterator.FlatRegionIterator;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@ -196,9 +199,16 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
|
||||
return minY;
|
||||
}
|
||||
|
||||
private static final BigDecimal PI = BigDecimal.valueOf(Math.PI);
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return (int) Math.floor(radius.getX() * radius.getZ() * Math.PI * getHeight());
|
||||
public long getVolume() {
|
||||
return BigDecimal.valueOf(radius.getX())
|
||||
.multiply(BigDecimal.valueOf(radius.getZ()))
|
||||
.multiply(PI)
|
||||
.multiply(BigDecimal.valueOf(getHeight()))
|
||||
.setScale(0, RoundingMode.FLOOR)
|
||||
.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +32,8 @@ import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ -92,10 +94,16 @@ public class EllipsoidRegion extends AbstractRegion {
|
||||
return center.toVector3().add(getRadius()).toBlockPoint();
|
||||
}
|
||||
|
||||
private static final BigDecimal ELLIPSOID_BASE_MULTIPLIER = BigDecimal.valueOf((4.0 / 3.0) * Math.PI);
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return (int) Math
|
||||
.floor((4.0 / 3.0) * Math.PI * radius.getX() * radius.getY() * radius.getZ());
|
||||
public long getVolume() {
|
||||
return ELLIPSOID_BASE_MULTIPLIER
|
||||
.multiply(BigDecimal.valueOf(radius.getX()))
|
||||
.multiply(BigDecimal.valueOf(radius.getY()))
|
||||
.multiply(BigDecimal.valueOf(radius.getZ()))
|
||||
.setScale(0, RoundingMode.FLOOR)
|
||||
.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,7 +53,7 @@ public class NullRegion implements Region {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
public long getVolume() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator;
|
||||
import com.sk89q.worldedit.regions.iterator.FlatRegionIterator;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@ -197,18 +199,22 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
double area = 0;
|
||||
public long getVolume() {
|
||||
long area = 0;
|
||||
int i, j = points.size() - 1;
|
||||
|
||||
for (i = 0; i < points.size(); ++i) {
|
||||
area += (points.get(j).getBlockX() + points.get(i).getBlockX())
|
||||
* (points.get(j).getBlockZ() - points.get(i).getBlockZ());
|
||||
long x = points.get(j).getBlockX() + points.get(i).getBlockX();
|
||||
long z = points.get(j).getBlockZ() - points.get(i).getBlockZ();
|
||||
area += x * z;
|
||||
j = i;
|
||||
}
|
||||
|
||||
return (int) Math.floor(Math.abs(area * 0.5)
|
||||
* (maxY - minY + 1));
|
||||
return BigDecimal.valueOf(area)
|
||||
.multiply(BigDecimal.valueOf(0.5))
|
||||
.abs()
|
||||
.setScale(0, RoundingMode.FLOOR)
|
||||
.longValue() * (maxY - minY + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,8 +32,10 @@ import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@ -74,14 +76,40 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
||||
* Get the number of blocks in the region.
|
||||
*
|
||||
* @return number of blocks
|
||||
* @deprecated use {@link Region#getVolume()} to prevent overflows
|
||||
*/
|
||||
@Deprecated
|
||||
default int getArea() {
|
||||
return (int) getVolume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of blocks in the region.
|
||||
*
|
||||
* <p>Note: This method <b>must</b> be overridden.</p>
|
||||
*
|
||||
* @return number of blocks
|
||||
*/
|
||||
default long getVolume() {
|
||||
// TODO Remove default status when getArea is removed.
|
||||
try {
|
||||
if (getClass().getMethod("getArea").getDeclaringClass().equals(Region.class)) {
|
||||
throw new IllegalStateException("Class " + getClass().getName() + " must override getVolume.");
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return getArea();
|
||||
}
|
||||
|
||||
/* FAWE code for getArea() before merge:
|
||||
default int getArea() {
|
||||
BlockVector3 min = getMinimumPoint();
|
||||
BlockVector3 max = getMaximumPoint();
|
||||
|
||||
return (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Get X-size.
|
||||
*
|
||||
|
@ -135,8 +135,31 @@ public interface RegionSelector {
|
||||
* Get the number of blocks inside the region.
|
||||
*
|
||||
* @return number of blocks, or -1 if undefined
|
||||
* @deprecated use {@link RegionSelector#getVolume()}
|
||||
*/
|
||||
int getArea();
|
||||
@Deprecated
|
||||
default int getArea() {
|
||||
return (int) getVolume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of blocks inside the region.
|
||||
*
|
||||
* <p>Note: This method <b>must</b> be overridden.</p>
|
||||
*
|
||||
* @return number of blocks, or -1 if undefined
|
||||
*/
|
||||
default long getVolume() {
|
||||
// TODO Remove default once getArea is removed
|
||||
try {
|
||||
if (getClass().getMethod("getArea").getDeclaringClass().equals(RegionSelector.class)) {
|
||||
throw new IllegalStateException("Class " + getClass().getName() + " must override getVolume.");
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return getArea();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the selector with changes to the region.
|
||||
|
@ -113,8 +113,8 @@ public class TransformRegion extends AbstractRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea(); // Cannot transform this
|
||||
public long getVolume() {
|
||||
return region.getVolume(); // Cannot transform this
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -170,8 +170,8 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea();
|
||||
public long getVolume() {
|
||||
return region.getVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -250,7 +250,7 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
|
||||
int lastVertexId = -1;
|
||||
for (BlockVector3 vertex : vertices) {
|
||||
vertexIds.put(vertex, ++lastVertexId);
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(lastVertexId, vertex, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(lastVertexId, vertex, getVolume()));
|
||||
}
|
||||
|
||||
for (Triangle triangle : triangles) {
|
||||
@ -273,8 +273,8 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion
|
||||
checkNotNull(session);
|
||||
|
||||
if (isDefined()) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,13 +161,13 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.cuboid.explain.primary-area",
|
||||
TextComponent.of(position1.toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else if (position1 != null) {
|
||||
player.printInfo(TranslatableComponent.of("worldedit.selection.cuboid.explain.primary", TextComponent.of(position1.toString())));
|
||||
}
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getVolume()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -180,13 +180,13 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.cuboid.explain.secondary-area",
|
||||
TextComponent.of(position2.toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else if (position2 != null) {
|
||||
player.printInfo(TranslatableComponent.of("worldedit.selection.cuboid.explain.secondary", TextComponent.of(position2.toString())));
|
||||
}
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos, getVolume()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -197,11 +197,11 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
|
||||
|
||||
if (position1 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getVolume()));
|
||||
}
|
||||
|
||||
if (position2 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getVolume()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
public long getVolume() {
|
||||
if (position1 == null) {
|
||||
return -1;
|
||||
}
|
||||
@ -277,17 +277,17 @@ public class CuboidRegionSelector implements RegionSelector, CUIRegion {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return region.getArea();
|
||||
return region.getVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeCUI(LocalSession session, Actor player) {
|
||||
if (position1 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, position1, getVolume()));
|
||||
}
|
||||
|
||||
if (position2 != null) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, position2, getVolume()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
|
||||
"worldedit.selection.cylinder.explain.secondary",
|
||||
TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getX())),
|
||||
TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getZ())),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else {
|
||||
player.printError(TranslatableComponent.of("worldedit.selection.cylinder.explain.secondary-missing"));
|
||||
@ -260,8 +260,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea();
|
||||
public long getVolume() {
|
||||
return region.getVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -273,8 +273,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion {
|
||||
@Override
|
||||
public void describeLegacyCUI(LocalSession session, Actor player) {
|
||||
if (isDefined()) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.ellipsoid.explain.primary-area",
|
||||
TextComponent.of(region.getCenter().toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
@ -169,7 +169,7 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.ellipsoid.explain.secondary-area",
|
||||
TextComponent.of(region.getRadius().toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
@ -238,8 +238,8 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea();
|
||||
public long getVolume() {
|
||||
return region.getVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -250,8 +250,8 @@ public class EllipsoidRegionSelector implements RegionSelector, CUIRegion {
|
||||
|
||||
@Override
|
||||
public void describeLegacyCUI(LocalSession session, Actor player) {
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getVolume()));
|
||||
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getVolume()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,7 +134,7 @@ public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.extend.explain.primary",
|
||||
TextComponent.of(pos.toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
|
||||
explainRegionAdjust(player, session);
|
||||
@ -145,7 +145,7 @@ public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.extend.explain.secondary",
|
||||
TextComponent.of(pos.toString()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
|
||||
explainRegionAdjust(player, session);
|
||||
|
@ -174,7 +174,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
|
||||
player.printInfo(TranslatableComponent.of("worldedit.selection.polygon2d.explain.primary", TextComponent.of(pos.toString())));
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getVolume()));
|
||||
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
|
||||
TextComponent.of(pos.toString())
|
||||
));
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getVolume()));
|
||||
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
|
||||
}
|
||||
|
||||
@ -247,8 +247,8 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return region.getArea();
|
||||
public long getVolume() {
|
||||
return region.getVolume();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +264,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
|
||||
public void describeCUI(LocalSession session, Actor player) {
|
||||
final List<BlockVector2> points = region.getPoints();
|
||||
for (int id = 0; id < points.size(); id++) {
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getArea()));
|
||||
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getVolume()));
|
||||
}
|
||||
|
||||
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
|
||||
|
@ -93,7 +93,7 @@ public class SphereRegionSelector extends EllipsoidRegionSelector {
|
||||
player.printInfo(TranslatableComponent.of(
|
||||
"worldedit.selection.sphere.explain.secondary-defined",
|
||||
TextComponent.of(region.getRadius().getX()),
|
||||
TextComponent.of(region.getArea())
|
||||
TextComponent.of(region.getVolume())
|
||||
));
|
||||
} else {
|
||||
player.printInfo(TranslatableComponent.of("worldedit.selection.sphere.explain.secondary", TextComponent.of(region.getRadius().getX())));
|
||||
|
@ -78,8 +78,8 @@ public class RequestSelection implements Region {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArea() {
|
||||
return getRegion().getArea();
|
||||
public long getVolume() {
|
||||
return getRegion().getVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.util.collection;
|
||||
|
||||
import com.google.common.collect.AbstractIterator;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
@ -36,6 +35,7 @@ import java.util.AbstractSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
@ -43,6 +43,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.sk89q.worldedit.math.BitMath.fixSign;
|
||||
import static com.sk89q.worldedit.math.BitMath.mask;
|
||||
|
||||
@ -51,12 +52,6 @@ import static com.sk89q.worldedit.math.BitMath.mask;
|
||||
*/
|
||||
public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
|
||||
|
||||
/* =========================
|
||||
IF YOU MAKE CHANGES TO THIS CLASS
|
||||
Re-run BlockMapTest with the blockmap.fulltesting=true system property.
|
||||
Or just temporarily remove the annotation disabling the related tests.
|
||||
========================= */
|
||||
|
||||
public static <V> BlockMap<V> create() {
|
||||
return create(() -> new Int2ObjectOpenHashMap<>(64, 0.9f));
|
||||
}
|
||||
@ -245,26 +240,65 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
|
||||
entrySet = es = new AbstractSet<Entry<BlockVector3, V>>() {
|
||||
@Override
|
||||
public Iterator<Entry<BlockVector3, V>> iterator() {
|
||||
return new AbstractIterator<Entry<BlockVector3, V>>() {
|
||||
return new Iterator<Entry<BlockVector3,V>>() {
|
||||
|
||||
private final ObjectIterator<Long2ObjectMap.Entry<Int2ObjectMap<V>>> primaryIterator
|
||||
= Long2ObjectMaps.fastIterator(maps);
|
||||
private long currentGroupKey;
|
||||
private Long2ObjectMap.Entry<Int2ObjectMap<V>> currentPrimaryEntry;
|
||||
private ObjectIterator<Int2ObjectMap.Entry<V>> secondaryIterator;
|
||||
private boolean finished;
|
||||
private LazyEntry next;
|
||||
|
||||
@Override
|
||||
protected Entry<BlockVector3, V> computeNext() {
|
||||
if (secondaryIterator == null || !secondaryIterator.hasNext()) {
|
||||
if (!primaryIterator.hasNext()) {
|
||||
return endOfData();
|
||||
public boolean hasNext() {
|
||||
if (finished) {
|
||||
return false;
|
||||
}
|
||||
if (next == null) {
|
||||
LazyEntry proposedNext = computeNext();
|
||||
if (proposedNext == null) {
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
next = proposedNext;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Long2ObjectMap.Entry<Int2ObjectMap<V>> next = primaryIterator.next();
|
||||
currentGroupKey = next.getLongKey();
|
||||
secondaryIterator = Int2ObjectMaps.fastIterator(next.getValue());
|
||||
private LazyEntry computeNext() {
|
||||
if (secondaryIterator == null || !secondaryIterator.hasNext()) {
|
||||
if (!primaryIterator.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
currentPrimaryEntry = primaryIterator.next();
|
||||
secondaryIterator = Int2ObjectMaps.fastIterator(currentPrimaryEntry.getValue());
|
||||
// be paranoid
|
||||
checkState(secondaryIterator.hasNext(),
|
||||
"Should not have an empty map entry, it should have been removed!");
|
||||
}
|
||||
Int2ObjectMap.Entry<V> next = secondaryIterator.next();
|
||||
return new LazyEntry(currentGroupKey, next.getIntKey(), next.getValue());
|
||||
return new LazyEntry(currentPrimaryEntry.getLongKey(), next.getIntKey(), next.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entry<BlockVector3, V> next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
LazyEntry tmp = next;
|
||||
next = null;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
secondaryIterator.remove();
|
||||
// ensure invariants hold
|
||||
if (currentPrimaryEntry.getValue().isEmpty()) {
|
||||
// the remove call cleared this map. call remove on the primary iter
|
||||
primaryIterator.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -364,13 +398,14 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
BlockVector3 vec = (BlockVector3) key;
|
||||
Int2ObjectMap<V> activeMap = maps.get(toGroupKey(vec));
|
||||
long groupKey = toGroupKey(vec);
|
||||
Int2ObjectMap<V> activeMap = maps.get(groupKey);
|
||||
if (activeMap == null) {
|
||||
return null;
|
||||
}
|
||||
V removed = activeMap.remove(toInnerKey(vec));
|
||||
if (activeMap.isEmpty()) {
|
||||
maps.remove(toGroupKey(vec));
|
||||
maps.remove(groupKey);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
@ -429,7 +464,9 @@ public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
|
||||
}
|
||||
if (o instanceof BlockMap) {
|
||||
// optimize by skipping entry translations:
|
||||
return maps.equals(((BlockMap) o).maps);
|
||||
@SuppressWarnings("unchecked")
|
||||
BlockMap<V> other = (BlockMap<V>) o;
|
||||
return maps.equals(other.maps);
|
||||
}
|
||||
return super.equals(o);
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
|
||||
= Int2IntMaps.fastIterator(commonMap);
|
||||
private final ObjectIterator<Entry<BaseBlock>> uncommonIter
|
||||
= Int2ObjectMaps.fastIterator(uncommonMap);
|
||||
private boolean lastNextFromCommon = false;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
@ -101,15 +102,26 @@ class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
|
||||
public Entry<BaseBlock> next() {
|
||||
if (commonIter.hasNext()) {
|
||||
Int2IntMap.Entry e = commonIter.next();
|
||||
lastNextFromCommon = true;
|
||||
return new BasicEntry<>(
|
||||
e.getIntKey(), assumeAsBlock(e.getIntValue())
|
||||
);
|
||||
}
|
||||
if (uncommonIter.hasNext()) {
|
||||
lastNextFromCommon = false;
|
||||
return uncommonIter.next();
|
||||
}
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (lastNextFromCommon) {
|
||||
commonIter.remove();
|
||||
} else {
|
||||
uncommonIter.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,49 +30,54 @@ import java.util.Iterator;
|
||||
|
||||
class VectorPositionList implements PositionList {
|
||||
|
||||
private final IntList delegate = new IntArrayList();
|
||||
private final IntList delegateX = new IntArrayList();
|
||||
private final IntList delegateY = new IntArrayList();
|
||||
private final IntList delegateZ = new IntArrayList();
|
||||
|
||||
@Override
|
||||
public BlockVector3 get(int index) {
|
||||
int ri = index * 3;
|
||||
return BlockVector3.at(
|
||||
delegate.getInt(ri),
|
||||
delegate.getInt(ri + 1),
|
||||
delegate.getInt(ri + 2));
|
||||
delegateX.getInt(index),
|
||||
delegateY.getInt(index),
|
||||
delegateZ.getInt(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(BlockVector3 vector) {
|
||||
delegate.add(vector.getX());
|
||||
delegate.add(vector.getY());
|
||||
delegate.add(vector.getZ());
|
||||
delegateX.add(vector.getX());
|
||||
delegateY.add(vector.getY());
|
||||
delegateZ.add(vector.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
return delegateX.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
delegate.clear();
|
||||
delegateX.clear();
|
||||
delegateY.clear();
|
||||
delegateZ.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<BlockVector3> iterator() {
|
||||
return new AbstractIterator<BlockVector3>() {
|
||||
|
||||
private final IntIterator iterator = delegate.iterator();
|
||||
private final IntIterator iteratorX = delegateX.iterator();
|
||||
private final IntIterator iteratorY = delegateY.iterator();
|
||||
private final IntIterator iteratorZ = delegateZ.iterator();
|
||||
|
||||
@Override
|
||||
protected BlockVector3 computeNext() {
|
||||
if (!iterator.hasNext()) {
|
||||
if (!iteratorX.hasNext()) {
|
||||
return endOfData();
|
||||
}
|
||||
return BlockVector3.at(
|
||||
iterator.nextInt(),
|
||||
iterator.nextInt(),
|
||||
iterator.nextInt());
|
||||
iteratorX.nextInt(),
|
||||
iteratorY.nextInt(),
|
||||
iteratorZ.nextInt());
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -81,17 +86,19 @@ class VectorPositionList implements PositionList {
|
||||
public Iterator<BlockVector3> reverseIterator() {
|
||||
return new AbstractIterator<BlockVector3>() {
|
||||
|
||||
private final IntListIterator iterator = delegate.listIterator(delegate.size());
|
||||
private final IntListIterator iteratorX = delegateX.listIterator(delegateX.size());
|
||||
private final IntListIterator iteratorY = delegateY.listIterator(delegateY.size());
|
||||
private final IntListIterator iteratorZ = delegateZ.listIterator(delegateZ.size());
|
||||
|
||||
@Override
|
||||
protected BlockVector3 computeNext() {
|
||||
if (!iterator.hasPrevious()) {
|
||||
if (!iteratorX.hasPrevious()) {
|
||||
return endOfData();
|
||||
}
|
||||
return BlockVector3.at(
|
||||
iterator.previousInt(),
|
||||
iterator.previousInt(),
|
||||
iterator.previousInt());
|
||||
iteratorX.previousInt(),
|
||||
iteratorY.previousInt(),
|
||||
iteratorZ.previousInt());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -31,13 +31,7 @@ public class TaskStateComparator implements Comparator<Task<?>> {
|
||||
public int compare(com.sk89q.worldedit.util.task.Task<?> o1, Task<?> o2) {
|
||||
int ordinal1 = o1.getState().ordinal();
|
||||
int ordinal2 = o2.getState().ordinal();
|
||||
if (ordinal1 < ordinal2) {
|
||||
return -1;
|
||||
} else if (ordinal1 > ordinal2) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return Integer.compare(ordinal1, ordinal2);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.math;
|
||||
|
||||
import com.sk89q.worldedit.util.test.VariedVectors;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@DisplayName("A 3D block vector")
|
||||
public class BlockVector3Test {
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true, divisionsXZ = 50, divisionsY = 50)
|
||||
@DisplayName("survives a round-trip through long-packing")
|
||||
void longPackingRoundTrip(BlockVector3 vec) {
|
||||
assertEquals(vec, BlockVector3.fromLongPackedForm(vec.toLongPackedForm()));
|
||||
}
|
||||
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util;
|
||||
|
||||
import com.google.common.collect.AbstractIterator;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.support.AnnotationConsumer;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Argument provider for various vectors.
|
||||
*/
|
||||
public final class VariedVectorsProvider implements ArgumentsProvider, AnnotationConsumer<VariedVectorsProvider.Test> {
|
||||
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ArgumentsSource(VariedVectorsProvider.class)
|
||||
@ParameterizedTest(name = ParameterizedTest.ARGUMENTS_PLACEHOLDER)
|
||||
public @interface Test {
|
||||
|
||||
/**
|
||||
* If {@code true}, provide a non-matching vector from
|
||||
* the existing vectors set as well. This will nearly
|
||||
* square the number of tests executed, since it will
|
||||
* test <em>every</em> non-matching vector.
|
||||
*/
|
||||
boolean provideNonMatching() default false;
|
||||
|
||||
}
|
||||
|
||||
private static final int WORLD_XZ_MINMAX = 30_000_000;
|
||||
private static final long WORLD_Y_MAX = Integer.MAX_VALUE;
|
||||
private static final long WORLD_Y_MIN = Integer.MIN_VALUE;
|
||||
|
||||
// For better coverage assurance, increase these values for a local Gradle run.
|
||||
// Don't do it for IntelliJ, it'll probably run out of memory.
|
||||
private static final int DIVISIONS_XZ = Integer.getInteger("variedvecs.divisions.xz", 5);
|
||||
private static final int DIVISIONS_Y = Integer.getInteger("variedvecs.divisions.y", 5);
|
||||
|
||||
private static final int XZ_STEP = (WORLD_XZ_MINMAX * 2) / DIVISIONS_XZ;
|
||||
private static final long Y_STEP = (WORLD_Y_MAX * 2) / DIVISIONS_Y;
|
||||
|
||||
private static final Set<BlockVector3> ALWAYS_INCLUDE =
|
||||
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
|
||||
BlockVector3.at(-WORLD_XZ_MINMAX, 0, -WORLD_XZ_MINMAX),
|
||||
BlockVector3.at(WORLD_XZ_MINMAX, 0, WORLD_XZ_MINMAX),
|
||||
BlockVector3.at(-WORLD_XZ_MINMAX, WORLD_Y_MAX, -WORLD_XZ_MINMAX),
|
||||
BlockVector3.at(WORLD_XZ_MINMAX, WORLD_Y_MAX, WORLD_XZ_MINMAX));
|
||||
|
||||
private boolean provideNonMatching;
|
||||
|
||||
@Override
|
||||
public void accept(Test test) {
|
||||
provideNonMatching = test.provideNonMatching();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
if (provideNonMatching) {
|
||||
return makeVectorsStream()
|
||||
.flatMap(vec -> makeVectorsStream().filter(v -> !v.equals(vec))
|
||||
.map(v -> Arguments.of(vec, v)));
|
||||
}
|
||||
return makeVectorsStream().map(Arguments::of);
|
||||
}
|
||||
|
||||
public static Stream<BlockVector3> makeVectorsStream() {
|
||||
return Stream.concat(
|
||||
ALWAYS_INCLUDE.stream(),
|
||||
Streams.stream(generateVectors()).filter(v -> !ALWAYS_INCLUDE.contains(v))
|
||||
);
|
||||
}
|
||||
|
||||
private static Iterator<BlockVector3> generateVectors() {
|
||||
return new AbstractIterator<BlockVector3>() {
|
||||
|
||||
private int x = -WORLD_XZ_MINMAX + 1;
|
||||
private int z = -WORLD_XZ_MINMAX + 1;
|
||||
private long y = WORLD_Y_MAX;
|
||||
|
||||
@Override
|
||||
protected BlockVector3 computeNext() {
|
||||
if (x > WORLD_XZ_MINMAX) {
|
||||
return endOfData();
|
||||
}
|
||||
BlockVector3 newVector = BlockVector3.at(x, (int) y, z);
|
||||
y += Y_STEP;
|
||||
if (y > WORLD_Y_MAX) {
|
||||
y = 0;
|
||||
z += XZ_STEP;
|
||||
if (z > WORLD_XZ_MINMAX) {
|
||||
z = -WORLD_XZ_MINMAX;
|
||||
x += XZ_STEP;
|
||||
}
|
||||
}
|
||||
return newVector;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -27,7 +27,8 @@ import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.Registry;
|
||||
import com.sk89q.worldedit.util.VariedVectorsProvider;
|
||||
import com.sk89q.worldedit.util.test.VariedVectorGenerator;
|
||||
import com.sk89q.worldedit.util.test.VariedVectors;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
@ -45,11 +46,11 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -63,24 +64,23 @@ import static org.junit.jupiter.api.Assumptions.assumeFalse;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@DisplayName("An ordered block map")
|
||||
class BlockMapTest {
|
||||
/*
|
||||
private static Platform mockedPlatform = mock(Platform.class);
|
||||
private static final Platform MOCKED_PLATFORM = mock(Platform.class);
|
||||
|
||||
@BeforeAll
|
||||
static void setupFakePlatform() {
|
||||
when(mockedPlatform.getRegistries()).thenReturn(new BundledRegistries() {
|
||||
when(MOCKED_PLATFORM.getRegistries()).thenReturn(new BundledRegistries() {
|
||||
});
|
||||
when(mockedPlatform.getCapabilities()).thenReturn(ImmutableMap.of(
|
||||
when(MOCKED_PLATFORM.getCapabilities()).thenReturn(ImmutableMap.of(
|
||||
Capability.WORLD_EDITING, Preference.PREFERRED,
|
||||
Capability.GAME_HOOKS, Preference.PREFERRED
|
||||
));
|
||||
PlatformManager platformManager = WorldEdit.getInstance().getPlatformManager();
|
||||
platformManager.register(mockedPlatform);
|
||||
platformManager.register(MOCKED_PLATFORM);
|
||||
|
||||
registerBlock("minecraft:air");
|
||||
registerBlock("minecraft:oak_wood");
|
||||
@ -88,7 +88,7 @@ class BlockMapTest {
|
||||
|
||||
@AfterAll
|
||||
static void tearDownFakePlatform() throws Exception {
|
||||
WorldEdit.getInstance().getPlatformManager().unregister(mockedPlatform);
|
||||
WorldEdit.getInstance().getPlatformManager().unregister(MOCKED_PLATFORM);
|
||||
Field map = Registry.class.getDeclaredField("map");
|
||||
map.setAccessible(true);
|
||||
((Map<?, ?>) map.get(BlockType.REGISTRY)).clear();
|
||||
@ -98,8 +98,6 @@ class BlockMapTest {
|
||||
BlockType.REGISTRY.register(id, new BlockType(id));
|
||||
}
|
||||
|
||||
@Mock
|
||||
private Function<? super BlockVector3, ? extends BaseBlock> function;
|
||||
@Mock
|
||||
private BiFunction<? super BlockVector3, ? super BaseBlock, ? extends BaseBlock> biFunction;
|
||||
@Mock
|
||||
@ -110,7 +108,7 @@ class BlockMapTest {
|
||||
private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock();
|
||||
private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock();
|
||||
|
||||
private BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
|
||||
private final BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
@ -186,14 +184,14 @@ class BlockMapTest {
|
||||
@DisplayName("never calls the forEach action")
|
||||
void neverCallsForEachAction() {
|
||||
map.forEach(biConsumer);
|
||||
verifyZeroInteractions(biConsumer);
|
||||
verifyNoMoreInteractions(biConsumer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("never calls the replaceAll function")
|
||||
void neverCallsReplaceAllFunction() {
|
||||
map.replaceAll(biFunction);
|
||||
verifyZeroInteractions(biFunction);
|
||||
verifyNoMoreInteractions(biFunction);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -254,63 +252,62 @@ class BlockMapTest {
|
||||
assertEquals(air, map.merge(BlockVector3.ZERO, air, mergeFunction));
|
||||
assertEquals(1, map.size());
|
||||
assertEquals(air, map.get(BlockVector3.ZERO));
|
||||
verifyZeroInteractions(mergeFunction);
|
||||
verifyNoMoreInteractions(mergeFunction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("after having an entry added")
|
||||
@EnabledIfSystemProperty(named = "blockmap.fulltesting", matches = "true")
|
||||
class AfterEntryAdded {
|
||||
|
||||
// Note: This section of tests would really benefit from
|
||||
// being able to parameterize classes. It's not part of JUnit
|
||||
// yet though: https://github.com/junit-team/junit5/issues/878
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("has a size of one")
|
||||
void hasSizeOne(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertEquals(1, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("is equal to another map with the same entry")
|
||||
void isEqualToSimilarMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertEquals(ImmutableMap.of(vec, air), map);
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("is not equal to another map with a different key")
|
||||
void isNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(ImmutableMap.of(nonMatch, air), map);
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("is not equal to another map with a different value")
|
||||
void isNotEqualToDifferentValueMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(ImmutableMap.of(vec, oakWood), map);
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("is not equal to an empty map")
|
||||
void isNotEqualToEmptyMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(ImmutableMap.of(), map);
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("has the same hashCode as another map with the same entry")
|
||||
void isHashCodeEqualToSimilarMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertEquals(ImmutableMap.of(vec, air).hashCode(), map.hashCode());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("has a different hashCode from another map with a different key")
|
||||
void isHashCodeNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
assumeFalse(vec.hashCode() == nonMatch.hashCode(),
|
||||
@ -319,35 +316,35 @@ class BlockMapTest {
|
||||
assertNotEquals(ImmutableMap.of(nonMatch, air).hashCode(), map.hashCode());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("has a different hashCode from another map with a different value")
|
||||
void isHashCodeNotEqualToDifferentValueMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(ImmutableMap.of(vec, oakWood).hashCode(), map.hashCode());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("has a different hashCode from an empty map")
|
||||
void isHashCodeNotEqualToEmptyMap(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(ImmutableMap.of().hashCode(), map.hashCode());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("returns value from get")
|
||||
void returnsValueFromGet(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("returns `null` from get with different key")
|
||||
void returnsValueFromGet(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
assertNotEquals(air, map.get(nonMatch));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("contains the key")
|
||||
void containsTheKey(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -356,7 +353,7 @@ class BlockMapTest {
|
||||
assertTrue(map.containsKey(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("contains the value")
|
||||
void containsTheValue(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -365,7 +362,7 @@ class BlockMapTest {
|
||||
assertTrue(map.containsValue(air));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("contains the entry")
|
||||
void containsTheEntry(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -373,21 +370,21 @@ class BlockMapTest {
|
||||
assertEquals(new AbstractMap.SimpleImmutableEntry<>(vec, air), map.entrySet().iterator().next());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("returns the provided value from getOrDefault")
|
||||
void returnsProvidedFromGetOrDefault(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertEquals(air, map.getOrDefault(vec, oakWood));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("returns the default value from getOrDefault with a different key")
|
||||
void returnsDefaultFromGetOrDefaultWrongKey(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
assertEquals(oakWood, map.getOrDefault(nonMatch, oakWood));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("calls the forEach action once")
|
||||
void neverCallsForEachAction(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -396,7 +393,7 @@ class BlockMapTest {
|
||||
verifyNoMoreInteractions(biConsumer);
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("replaces value using replaceAll")
|
||||
void neverCallsReplaceAllFunction(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -404,7 +401,7 @@ class BlockMapTest {
|
||||
assertEquals(oakWood, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("does not insert on `putIfAbsent`")
|
||||
void noInsertOnPutIfAbsent(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -413,7 +410,7 @@ class BlockMapTest {
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("inserts on `putIfAbsent` to a different key")
|
||||
void insertOnPutIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
@ -423,7 +420,7 @@ class BlockMapTest {
|
||||
assertEquals(oakWood, map.get(nonMatch));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("remove(key) returns the old value")
|
||||
void removeKeyReturnsOldValue(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -431,7 +428,27 @@ class BlockMapTest {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test
|
||||
@DisplayName("keySet().remove(key) removes the entry from the map")
|
||||
void keySetRemovePassesThrough(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
assertTrue(map.keySet().remove(vec));
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectors.Test
|
||||
@DisplayName("entrySet().iterator().remove() removes the entry from the map")
|
||||
void entrySetIteratorRemovePassesThrough(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
Iterator<Map.Entry<BlockVector3, BaseBlock>> iterator = map.entrySet().iterator();
|
||||
assertTrue(iterator.hasNext());
|
||||
Map.Entry<BlockVector3, BaseBlock> entry = iterator.next();
|
||||
assertEquals(entry.getKey(), vec);
|
||||
iterator.remove();
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("remove(nonMatch) returns null")
|
||||
void removeNonMatchingKeyReturnsNull(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
@ -439,7 +456,7 @@ class BlockMapTest {
|
||||
assertEquals(1, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("remove(key, value) returns true")
|
||||
void removeKeyValueReturnsTrue(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -447,7 +464,7 @@ class BlockMapTest {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("remove(key, value) returns false for wrong value")
|
||||
void removeKeyValueReturnsFalseWrongValue(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -455,7 +472,7 @@ class BlockMapTest {
|
||||
assertEquals(1, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("replaces value at key")
|
||||
void replacesValueAtKey(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -469,7 +486,7 @@ class BlockMapTest {
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("does not replace value at different key")
|
||||
void doesNotReplaceAtDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
@ -483,7 +500,7 @@ class BlockMapTest {
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("does not insert on computeIfAbsent")
|
||||
void doesNotInsertComputeIfAbsent(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -495,7 +512,7 @@ class BlockMapTest {
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("inserts on computeIfAbsent with different key")
|
||||
void insertsOnComputeIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
@ -508,7 +525,7 @@ class BlockMapTest {
|
||||
assertEquals(oakWood, map.get(nonMatch));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("replaces on compute")
|
||||
void replaceOnCompute(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -523,7 +540,7 @@ class BlockMapTest {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test(provideNonMatching = true)
|
||||
@VariedVectors.Test(provideNonMatching = true)
|
||||
@DisplayName("inserts on compute with different key")
|
||||
void insertOnComputeDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
|
||||
map.put(vec, air);
|
||||
@ -540,7 +557,7 @@ class BlockMapTest {
|
||||
assertEquals(air, map.get(vec));
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("replaces on computeIfPresent")
|
||||
void replacesOnComputeIfPresent(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -555,7 +572,7 @@ class BlockMapTest {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
@VariedVectorsProvider.Test
|
||||
@VariedVectors.Test
|
||||
@DisplayName("inserts on merge, with call to merge function")
|
||||
void insertsOnMerge(BlockVector3 vec) {
|
||||
map.put(vec, air);
|
||||
@ -573,7 +590,9 @@ class BlockMapTest {
|
||||
@Test
|
||||
@DisplayName("contains all inserted vectors")
|
||||
void containsAllInsertedVectors() {
|
||||
Set<BlockVector3> allVectors = VariedVectorsProvider.makeVectorsStream().collect(Collectors.toSet());
|
||||
Set<BlockVector3> allVectors = new VariedVectorGenerator()
|
||||
.makeVectorsStream()
|
||||
.collect(Collectors.toSet());
|
||||
for (BlockVector3 vec : allVectors) {
|
||||
map.put(vec, air);
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.collection;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.test.VariedVectors;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
abstract class PositionListTest {
|
||||
|
||||
static class Long extends PositionListTest {
|
||||
protected Long() {
|
||||
super(new LongPositionList());
|
||||
}
|
||||
}
|
||||
|
||||
static class Vector extends PositionListTest {
|
||||
protected Vector() {
|
||||
super(new VectorPositionList());
|
||||
}
|
||||
}
|
||||
|
||||
private final PositionList positionList;
|
||||
|
||||
protected PositionListTest(PositionList positionList) {
|
||||
this.positionList = positionList;
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling add(vec) increases size by 1")
|
||||
void addIncreasesSizeByOne(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertEquals(1, positionList.size());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling get(0) after add(vec) returns vec")
|
||||
void canGetVectorAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertEquals(vec, positionList.get(0));
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling iterator().hasNext() after add(vec) returns true")
|
||||
void hasNextAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertTrue(positionList.iterator().hasNext());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling iterator().next() after add(vec) returns vec")
|
||||
void nextAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertEquals(vec, positionList.iterator().next());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling reverseIterator().hasNext() after add(vec) returns true")
|
||||
void reverseHasNextAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertTrue(positionList.reverseIterator().hasNext());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling reverseIterator().next() after add(vec) returns vec")
|
||||
void reverseNextAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
assertEquals(vec, positionList.reverseIterator().next());
|
||||
}
|
||||
|
||||
@VariedVectors.Test(capToVanilla = true)
|
||||
@DisplayName("calling clear() after add(vec) makes the size() zero")
|
||||
void clearAfterAdd(BlockVector3 vec) {
|
||||
positionList.add(vec);
|
||||
positionList.clear();
|
||||
assertEquals(0, positionList.size());
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.test;
|
||||
|
||||
import com.google.common.collect.AbstractIterator;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class VariedVectorGenerator {
|
||||
|
||||
// For better coverage assurance, increase these values for a local Gradle run.
|
||||
// Don't do it for IntelliJ, it'll probably run out of memory.
|
||||
private static final int DEFAULT_DIVISIONS_XZ =
|
||||
Integer.getInteger("variedvecs.divisions.xz", 5);
|
||||
private static final int DEFAULT_DIVISIONS_Y =
|
||||
Integer.getInteger("variedvecs.divisions.y", 5);
|
||||
|
||||
public final int divisionsXZ;
|
||||
public final int divisionsY;
|
||||
public final int maxXZ;
|
||||
public final long maxY;
|
||||
public final int xzStep;
|
||||
public final long yStep;
|
||||
public final Set<BlockVector3> alwaysInclude;
|
||||
|
||||
public VariedVectorGenerator() {
|
||||
this(false, -1, -1);
|
||||
}
|
||||
|
||||
public VariedVectorGenerator(boolean vanilla, int divisionsXZ, int divisionsY) {
|
||||
this.divisionsXZ = divisionsXZ == -1 ? DEFAULT_DIVISIONS_XZ : divisionsXZ;
|
||||
this.divisionsY = divisionsY == -1 ? DEFAULT_DIVISIONS_Y : divisionsY;
|
||||
maxXZ = 30_000_000;
|
||||
maxY = vanilla ? 255 : Integer.MAX_VALUE;
|
||||
xzStep = (maxXZ * 2) / this.divisionsXZ;
|
||||
yStep = (maxY * 2) / this.divisionsY;
|
||||
alwaysInclude =
|
||||
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
|
||||
BlockVector3.at(-maxXZ, 0, -maxXZ),
|
||||
BlockVector3.at(maxXZ, 0, maxXZ),
|
||||
BlockVector3.at(-maxXZ, maxY, -maxXZ),
|
||||
BlockVector3.at(maxXZ, maxY, maxXZ));
|
||||
}
|
||||
|
||||
public Stream<BlockVector3> makeVectorsStream() {
|
||||
return Stream.concat(
|
||||
alwaysInclude.stream(),
|
||||
Streams.stream(generateVectors()).filter(v -> !alwaysInclude.contains(v))
|
||||
);
|
||||
}
|
||||
|
||||
private Iterator<BlockVector3> generateVectors() {
|
||||
return new AbstractIterator<BlockVector3>() {
|
||||
|
||||
private int x = -maxXZ + 1;
|
||||
private int z = -maxXZ + 1;
|
||||
private long y = maxY;
|
||||
|
||||
@Override
|
||||
protected BlockVector3 computeNext() {
|
||||
if (x > maxXZ) {
|
||||
return endOfData();
|
||||
}
|
||||
BlockVector3 newVector = BlockVector3.at(x, (int) y, z);
|
||||
y += yStep;
|
||||
if (y > maxY) {
|
||||
y = 0;
|
||||
z += xzStep;
|
||||
if (z > maxXZ) {
|
||||
z = -maxXZ;
|
||||
x += xzStep;
|
||||
}
|
||||
}
|
||||
return newVector;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.util.test;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
import org.junit.jupiter.params.support.AnnotationConsumer;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Argument provider for various vectors.
|
||||
*/
|
||||
public final class VariedVectors implements ArgumentsProvider, AnnotationConsumer<VariedVectors.Test> {
|
||||
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ArgumentsSource(VariedVectors.class)
|
||||
@ParameterizedTest(name = ParameterizedTest.ARGUMENTS_PLACEHOLDER)
|
||||
public @interface Test {
|
||||
|
||||
/**
|
||||
* If {@code true}, provide a non-matching vector from
|
||||
* the existing vectors set as well. This will nearly
|
||||
* square the number of tests executed, since it will
|
||||
* test <em>every</em> non-matching vector.
|
||||
*/
|
||||
boolean provideNonMatching() default false;
|
||||
|
||||
/**
|
||||
* If {@code true}, only provide vectors inside the range of Vanilla MC.
|
||||
* This caps the Y value to 255.
|
||||
*/
|
||||
boolean capToVanilla() default false;
|
||||
|
||||
int divisionsXZ() default -1;
|
||||
|
||||
int divisionsY() default -1;
|
||||
|
||||
}
|
||||
|
||||
private boolean provideNonMatching;
|
||||
private VariedVectorGenerator generator;
|
||||
|
||||
@Override
|
||||
public void accept(Test test) {
|
||||
provideNonMatching = test.provideNonMatching();
|
||||
generator = new VariedVectorGenerator(test.capToVanilla(), test.divisionsXZ(), test.divisionsY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||
if (provideNonMatching) {
|
||||
return generator.makeVectorsStream()
|
||||
.flatMap(vec -> generator.makeVectorsStream().filter(v -> !v.equals(vec))
|
||||
.map(v -> Arguments.of(vec, v)));
|
||||
}
|
||||
return generator.makeVectorsStream().map(Arguments::of);
|
||||
}
|
||||
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren