Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-05 02:50:05 +01:00
Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit into main
Dieser Commit ist enthalten in:
Commit
b5d9ee1532
@ -419,14 +419,14 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (createCopy) {
|
if (createCopy) {
|
||||||
copy.storeBiomes(currentBiomes);
|
copy.storeBiomes(currentBiomes);
|
||||||
}
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int y = 0, i = 0; y < 64; y++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
final BiomeType biome = biomes[i];
|
for (int x = 0; x < 4; x++, i++) {
|
||||||
if (biome != null) {
|
final BiomeType biome = biomes[i];
|
||||||
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
if (biome != null) {
|
||||||
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(craftBiome);
|
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
||||||
for (int y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(craftBiome);
|
||||||
currentBiomes.setBiome(x >> 2, y >> 2, z >> 2, nmsBiome);
|
currentBiomes.setBiome(x, y, z, nmsBiome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,14 +421,14 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (createCopy) {
|
if (createCopy) {
|
||||||
copy.storeBiomes(currentBiomes);
|
copy.storeBiomes(currentBiomes);
|
||||||
}
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int y = 0, i = 0; y < 64; y++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
final BiomeType biome = biomes[i];
|
for (int x = 0; x < 4; x++, i++) {
|
||||||
if (biome != null) {
|
final BiomeType biome = biomes[i];
|
||||||
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
if (biome != null) {
|
||||||
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(craftBiome);
|
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
||||||
for (int y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(craftBiome);
|
||||||
currentBiomes.setBiome(x >> 2, y >> 2, z >> 2, nmsBiome);
|
currentBiomes.setBiome(x, y, z, nmsBiome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.AbstractSet;
|
import java.util.AbstractSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -72,7 +73,6 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
@ -424,14 +424,14 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (createCopy) {
|
if (createCopy) {
|
||||||
copy.storeBiomes(currentBiomes);
|
copy.storeBiomes(currentBiomes);
|
||||||
}
|
}
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int y = 0, i = 0; y < 64; y++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
final BiomeType biome = biomes[i];
|
for (int x = 0; x < 4; x++, i++) {
|
||||||
if (biome != null) {
|
final BiomeType biome = biomes[i];
|
||||||
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
if (biome != null) {
|
||||||
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(nmsWorld.r().b(IRegistry.ay), craftBiome);
|
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
||||||
for (int y = 0; y < FaweCache.IMP.WORLD_HEIGHT; y++) {
|
BiomeBase nmsBiome = CraftBlock.biomeToBiomeBase(nmsWorld.r().b(IRegistry.ay), craftBiome);
|
||||||
currentBiomes.setBiome(x >> 2, y >> 2, z >> 2, nmsBiome);
|
currentBiomes.setBiome(x, y, z, nmsBiome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class BukkitPlayer extends AbstractPlayerActor {
|
public class BukkitPlayer extends AbstractPlayerActor {
|
||||||
@ -74,19 +75,29 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
private final Player player;
|
private final Player player;
|
||||||
private final WorldEditPlugin plugin;
|
private final WorldEditPlugin plugin;
|
||||||
private final PermissionAttachment permAttachment;
|
private final PermissionAttachment permAttachment;
|
||||||
|
/**
|
||||||
public BukkitPlayer(Player player) {
|
* This constructs a new {@link BukkitPlayer} for the given {@link Player}.
|
||||||
super(getExistingMap(WorldEditPlugin.getInstance(), player));
|
*
|
||||||
|
* @param player The corresponding {@link Player} or null if you need a null WorldEdit player for some reason.
|
||||||
|
*/
|
||||||
|
public BukkitPlayer(@Nullable Player player) {
|
||||||
|
super(player != null ? getExistingMap(WorldEditPlugin.getInstance(), player) : new ConcurrentHashMap<>());
|
||||||
this.plugin = WorldEditPlugin.getInstance();
|
this.plugin = WorldEditPlugin.getInstance();
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BukkitPlayer(WorldEditPlugin plugin, Player player) {
|
/**
|
||||||
|
* This constructs a new {@link BukkitPlayer} for the given {@link Player}.
|
||||||
|
*
|
||||||
|
* @param plugin The running instance of {@link WorldEditPlugin}
|
||||||
|
* @param player The corresponding {@link Player} or null if you need a null WorldEdit player for some reason.
|
||||||
|
*/
|
||||||
|
public BukkitPlayer(@Nonnull WorldEditPlugin plugin, @Nullable Player player) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
||||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
if (player != null && Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||||
loadClipboardFromDisk();
|
loadClipboardFromDisk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.world.RegenOptions;
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
@ -266,9 +267,13 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
//Setting Blocks
|
//Setting Blocks
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
boolean genbiomes = options.shouldRegenBiomes();
|
boolean genbiomes = options.shouldRegenBiomes();
|
||||||
|
boolean hasBiome = options.hasBiomeType();
|
||||||
|
BiomeType biome = options.getBiomeType();
|
||||||
for (BlockVector3 vec : region) {
|
for (BlockVector3 vec : region) {
|
||||||
target.setBlock(vec, source.getBlock(vec));
|
target.setBlock(vec, source.getBlock(vec));
|
||||||
if (genbiomes) {
|
if (hasBiome) {
|
||||||
|
target.setBiome(vec, biome);
|
||||||
|
} else if (genbiomes) {
|
||||||
target.setBiome(vec, source.getBiome(vec));
|
target.setBiome(vec, source.getBiome(vec));
|
||||||
}
|
}
|
||||||
// realExtent.setSkyLight(vec, extent.getSkyLight(vec));
|
// realExtent.setSkyLight(vec, extent.getSkyLight(vec));
|
||||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.beta.IChunkCache;
|
import com.boydti.fawe.beta.IChunkCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_15_2.BukkitGetBlocks_1_15_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_15_2.BukkitGetBlocks_1_15_2;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
@ -53,6 +54,7 @@ import net.minecraft.server.v1_15_R1.IChunkAccess;
|
|||||||
import net.minecraft.server.v1_15_R1.IRegistry;
|
import net.minecraft.server.v1_15_R1.IRegistry;
|
||||||
import net.minecraft.server.v1_15_R1.LightEngineThreaded;
|
import net.minecraft.server.v1_15_R1.LightEngineThreaded;
|
||||||
import net.minecraft.server.v1_15_R1.LinearCongruentialGenerator;
|
import net.minecraft.server.v1_15_R1.LinearCongruentialGenerator;
|
||||||
|
import net.minecraft.server.v1_15_R1.MinecraftKey;
|
||||||
import net.minecraft.server.v1_15_R1.MinecraftServer;
|
import net.minecraft.server.v1_15_R1.MinecraftServer;
|
||||||
import net.minecraft.server.v1_15_R1.NBTTagCompound;
|
import net.minecraft.server.v1_15_R1.NBTTagCompound;
|
||||||
import net.minecraft.server.v1_15_R1.NoiseGeneratorPerlin;
|
import net.minecraft.server.v1_15_R1.NoiseGeneratorPerlin;
|
||||||
@ -182,6 +184,16 @@ public class Regen_v1_15_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
@Override
|
@Override
|
||||||
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BiomeBase singleBiome = options.hasBiomeType() ? IRegistry.BIOME.get(MinecraftKey.a(options.getBiomeType().getId())) : null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase a(int i, int k, int j) {
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
return singleBiome;
|
||||||
|
}
|
||||||
|
return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k);
|
||||||
|
}
|
||||||
}).get();
|
}).get();
|
||||||
freshNMSWorld.savingDisabled = true;
|
freshNMSWorld.savingDisabled = true;
|
||||||
removeWorldFromWorldsMap();
|
removeWorldFromWorldsMap();
|
||||||
@ -358,15 +370,34 @@ public class Regen_v1_15_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
//init new WorldChunkManagerOverworld
|
//init new WorldChunkManagerOverworld
|
||||||
BiomeLayoutOverworldConfiguration biomeconfig = new BiomeLayoutOverworldConfiguration(freshNMSWorld.getWorldData())
|
BiomeLayoutOverworldConfiguration biomeconfig = new BiomeLayoutOverworldConfiguration(freshNMSWorld.getWorldData())
|
||||||
.a((GeneratorSettingsOverworld) originalChunkProvider.getChunkGenerator().getSettings());
|
.a((GeneratorSettingsOverworld) originalChunkProvider.getChunkGenerator().getSettings());
|
||||||
chunkManager = new WorldChunkManagerOverworld(biomeconfig);
|
|
||||||
|
|
||||||
//replace genLayer
|
|
||||||
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, biomeconfig.b(), biomeconfig.c(), (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, biomeconfig.b(), biomeconfig.c(), (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
||||||
genLayerField.set(chunkManager, new FastGenLayer(factory));
|
if (options.hasBiomeType()) {
|
||||||
|
BiomeBase biome = IRegistry.BIOME.get(MinecraftKey.a(options.getBiomeType().getId()));
|
||||||
|
chunkManager = new SingleBiomeWorldChunkManagerOverworld(biome);
|
||||||
|
} else {
|
||||||
|
chunkManager = new WorldChunkManagerOverworld(biomeconfig);
|
||||||
|
//replace genlayer
|
||||||
|
genLayerField.set(chunkManager, new FastGenLayer(factory));
|
||||||
|
}
|
||||||
|
|
||||||
return chunkManager;
|
return chunkManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SingleBiomeWorldChunkManagerOverworld extends WorldChunkManager {
|
||||||
|
|
||||||
|
private final BiomeBase biome;
|
||||||
|
|
||||||
|
public SingleBiomeWorldChunkManagerOverworld(BiomeBase biome) {
|
||||||
|
super(ImmutableSet.of(biome));
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase getBiome(int i, int i1, int i2) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
||||||
|
|
||||||
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
||||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.beta.IChunkGet;
|
|||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_1.BukkitGetBlocks_1_16_1;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_1.BukkitGetBlocks_1_16_1;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Dynamic;
|
import com.mojang.serialization.Dynamic;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
||||||
@ -17,6 +18,7 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -53,15 +55,14 @@ import net.minecraft.server.v1_16_R1.GeneratorSettings;
|
|||||||
import net.minecraft.server.v1_16_R1.GeneratorSettingsFlat;
|
import net.minecraft.server.v1_16_R1.GeneratorSettingsFlat;
|
||||||
import net.minecraft.server.v1_16_R1.IChunkAccess;
|
import net.minecraft.server.v1_16_R1.IChunkAccess;
|
||||||
import net.minecraft.server.v1_16_R1.IRegistry;
|
import net.minecraft.server.v1_16_R1.IRegistry;
|
||||||
import net.minecraft.server.v1_16_R1.IRegistryCustom;
|
|
||||||
import net.minecraft.server.v1_16_R1.LightEngineThreaded;
|
import net.minecraft.server.v1_16_R1.LightEngineThreaded;
|
||||||
import net.minecraft.server.v1_16_R1.LinearCongruentialGenerator;
|
import net.minecraft.server.v1_16_R1.LinearCongruentialGenerator;
|
||||||
|
import net.minecraft.server.v1_16_R1.MinecraftKey;
|
||||||
import net.minecraft.server.v1_16_R1.MinecraftServer;
|
import net.minecraft.server.v1_16_R1.MinecraftServer;
|
||||||
import net.minecraft.server.v1_16_R1.NBTBase;
|
import net.minecraft.server.v1_16_R1.NBTBase;
|
||||||
import net.minecraft.server.v1_16_R1.NBTTagCompound;
|
import net.minecraft.server.v1_16_R1.NBTTagCompound;
|
||||||
import net.minecraft.server.v1_16_R1.NoiseGeneratorPerlin;
|
import net.minecraft.server.v1_16_R1.NoiseGeneratorPerlin;
|
||||||
import net.minecraft.server.v1_16_R1.ProtoChunk;
|
import net.minecraft.server.v1_16_R1.ProtoChunk;
|
||||||
import net.minecraft.server.v1_16_R1.RegistryReadOps;
|
|
||||||
import net.minecraft.server.v1_16_R1.ResourceKey;
|
import net.minecraft.server.v1_16_R1.ResourceKey;
|
||||||
import net.minecraft.server.v1_16_R1.World;
|
import net.minecraft.server.v1_16_R1.World;
|
||||||
import net.minecraft.server.v1_16_R1.WorldChunkManager;
|
import net.minecraft.server.v1_16_R1.WorldChunkManager;
|
||||||
@ -201,6 +202,16 @@ public class Regen_v1_16_R1 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
@Override
|
@Override
|
||||||
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BiomeBase singleBiome = options.hasBiomeType() ? IRegistry.BIOME.get(MinecraftKey.a(options.getBiomeType().getId())) : null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase a(int i, int j, int k) {
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
return singleBiome;
|
||||||
|
}
|
||||||
|
return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k);
|
||||||
|
}
|
||||||
}).get();
|
}).get();
|
||||||
freshNMSWorld.savingDisabled = true;
|
freshNMSWorld.savingDisabled = true;
|
||||||
removeWorldFromWorldsMap();
|
removeWorldFromWorldsMap();
|
||||||
@ -398,16 +409,41 @@ public class Regen_v1_16_R1 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
|
|
||||||
//init new WorldChunkManagerOverworld
|
//init new WorldChunkManagerOverworld
|
||||||
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
|
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
|
||||||
boolean largebiomes = largeBiomesField.getBoolean(chunkManager);
|
boolean largeBiomes = largeBiomesField.getBoolean(chunkManager);
|
||||||
chunkManager = new WorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largebiomes);
|
|
||||||
|
|
||||||
//replace genLayer
|
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, legacyBiomeInitLayer, largeBiomes ? 6 : 4, 4, (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
||||||
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, legacyBiomeInitLayer, largebiomes ? 6 : 4, 4, (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
if (options.hasBiomeType()) {
|
||||||
genLayerField.set(chunkManager, new FastGenLayer(factory));
|
BiomeBase biome = IRegistry.BIOME.get(MinecraftKey.a(options.getBiomeType().getId()));
|
||||||
|
chunkManager = new SingleBiomeWorldChunkManagerOverworld(biome);
|
||||||
|
} else {
|
||||||
|
chunkManager = new WorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largeBiomes);
|
||||||
|
//replace genLayer
|
||||||
|
genLayerField.set(chunkManager, new FastGenLayer(factory));
|
||||||
|
}
|
||||||
|
|
||||||
return chunkManager;
|
return chunkManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SingleBiomeWorldChunkManagerOverworld extends WorldChunkManager {
|
||||||
|
|
||||||
|
private final BiomeBase biome;
|
||||||
|
|
||||||
|
public SingleBiomeWorldChunkManagerOverworld(BiomeBase biome) {
|
||||||
|
super(Arrays.asList(biome));
|
||||||
|
this.biome = biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Codec<? extends WorldChunkManager> a() {
|
||||||
|
return WorldChunkManagerOverworld.e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase getBiome(int i, int i1, int i2) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
||||||
|
|
||||||
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
||||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.beta.IChunkGet;
|
|||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_2.BukkitGetBlocks_1_16_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_2.BukkitGetBlocks_1_16_2;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Dynamic;
|
import com.mojang.serialization.Dynamic;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
|
||||||
@ -28,6 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.LongFunction;
|
import java.util.function.LongFunction;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.server.v1_16_R2.Area;
|
import net.minecraft.server.v1_16_R2.Area;
|
||||||
import net.minecraft.server.v1_16_R2.AreaContextTransformed;
|
import net.minecraft.server.v1_16_R2.AreaContextTransformed;
|
||||||
@ -56,11 +58,14 @@ import net.minecraft.server.v1_16_R2.IRegistry;
|
|||||||
import net.minecraft.server.v1_16_R2.IRegistryCustom;
|
import net.minecraft.server.v1_16_R2.IRegistryCustom;
|
||||||
import net.minecraft.server.v1_16_R2.LightEngineThreaded;
|
import net.minecraft.server.v1_16_R2.LightEngineThreaded;
|
||||||
import net.minecraft.server.v1_16_R2.LinearCongruentialGenerator;
|
import net.minecraft.server.v1_16_R2.LinearCongruentialGenerator;
|
||||||
|
import net.minecraft.server.v1_16_R2.MinecraftKey;
|
||||||
import net.minecraft.server.v1_16_R2.MinecraftServer;
|
import net.minecraft.server.v1_16_R2.MinecraftServer;
|
||||||
import net.minecraft.server.v1_16_R2.NBTBase;
|
import net.minecraft.server.v1_16_R2.NBTBase;
|
||||||
import net.minecraft.server.v1_16_R2.NBTTagCompound;
|
import net.minecraft.server.v1_16_R2.NBTTagCompound;
|
||||||
import net.minecraft.server.v1_16_R2.NoiseGeneratorPerlin;
|
import net.minecraft.server.v1_16_R2.NoiseGeneratorPerlin;
|
||||||
import net.minecraft.server.v1_16_R2.ProtoChunk;
|
import net.minecraft.server.v1_16_R2.ProtoChunk;
|
||||||
|
import net.minecraft.server.v1_16_R2.RegistryGeneration;
|
||||||
|
import net.minecraft.server.v1_16_R2.RegistryMaterials;
|
||||||
import net.minecraft.server.v1_16_R2.RegistryReadOps;
|
import net.minecraft.server.v1_16_R2.RegistryReadOps;
|
||||||
import net.minecraft.server.v1_16_R2.ResourceKey;
|
import net.minecraft.server.v1_16_R2.ResourceKey;
|
||||||
import net.minecraft.server.v1_16_R2.World;
|
import net.minecraft.server.v1_16_R2.World;
|
||||||
@ -202,6 +207,16 @@ public class Regen_v1_16_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
@Override
|
@Override
|
||||||
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
public void doTick(BooleanSupplier booleansupplier) { //no ticking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BiomeBase singleBiome = options.hasBiomeType() ? RegistryGeneration.WORLDGEN_BIOME.get(MinecraftKey.a(options.getBiomeType().getId())) : null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase a(int i, int j, int k) {
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
return singleBiome;
|
||||||
|
}
|
||||||
|
return this.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(i, j, k);
|
||||||
|
}
|
||||||
}).get();
|
}).get();
|
||||||
freshNMSWorld.savingDisabled = true;
|
freshNMSWorld.savingDisabled = true;
|
||||||
removeWorldFromWorldsMap();
|
removeWorldFromWorldsMap();
|
||||||
@ -395,8 +410,6 @@ public class Regen_v1_16_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
largeBiomesField.setAccessible(true);
|
largeBiomesField.setAccessible(true);
|
||||||
Field biomeRegistryField = WorldChunkManagerOverworld.class.getDeclaredField("k");
|
Field biomeRegistryField = WorldChunkManagerOverworld.class.getDeclaredField("k");
|
||||||
biomeRegistryField.setAccessible(true);
|
biomeRegistryField.setAccessible(true);
|
||||||
Field genLayerField = WorldChunkManagerOverworld.class.getDeclaredField("f");
|
|
||||||
genLayerField.setAccessible(true);
|
|
||||||
Field areaLazyField = GenLayer.class.getDeclaredField("b");
|
Field areaLazyField = GenLayer.class.getDeclaredField("b");
|
||||||
areaLazyField.setAccessible(true);
|
areaLazyField.setAccessible(true);
|
||||||
Method initAreaFactoryMethod = GenLayers.class.getDeclaredMethod("a", boolean.class, int.class, int.class, LongFunction.class);
|
Method initAreaFactoryMethod = GenLayers.class.getDeclaredMethod("a", boolean.class, int.class, int.class, LongFunction.class);
|
||||||
@ -405,16 +418,52 @@ public class Regen_v1_16_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
|
|||||||
//init new WorldChunkManagerOverworld
|
//init new WorldChunkManagerOverworld
|
||||||
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
|
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
|
||||||
boolean largebiomes = largeBiomesField.getBoolean(chunkManager);
|
boolean largebiomes = largeBiomesField.getBoolean(chunkManager);
|
||||||
IRegistry<BiomeBase> biomeRegistry = (IRegistry<BiomeBase>) biomeRegistryField.get(chunkManager);
|
IRegistry<BiomeBase> biomeRegistrynms = (IRegistry<BiomeBase>) biomeRegistryField.get(chunkManager);
|
||||||
chunkManager = new WorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largebiomes, biomeRegistry);
|
IRegistry<BiomeBase> biomeRegistry;
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
BiomeBase biome = RegistryGeneration.WORLDGEN_BIOME.get(MinecraftKey.a(options.getBiomeType().getId()));
|
||||||
|
biomeRegistry = new RegistryMaterials<>(ResourceKey.a(new MinecraftKey("fawe_biomes")), Lifecycle.experimental());
|
||||||
|
((RegistryMaterials) biomeRegistry).a(0, RegistryGeneration.WORLDGEN_BIOME.c(biome).get(), biome, Lifecycle.experimental());
|
||||||
|
} else {
|
||||||
|
biomeRegistry = biomeRegistrynms;
|
||||||
|
}
|
||||||
|
chunkManager = new FastWorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largebiomes, biomeRegistry);
|
||||||
|
|
||||||
//replace genLayer
|
//replace genLayer
|
||||||
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, legacyBiomeInitLayer, largebiomes ? 6 : 4, 4, (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, legacyBiomeInitLayer, largebiomes ? 6 : 4, 4, (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
|
||||||
genLayerField.set(chunkManager, new FastGenLayer(factory));
|
((FastWorldChunkManagerOverworld) chunkManager).genLayer = new FastGenLayer(factory);
|
||||||
|
|
||||||
return chunkManager;
|
return chunkManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FastWorldChunkManagerOverworld extends WorldChunkManager {
|
||||||
|
|
||||||
|
private GenLayer genLayer;
|
||||||
|
private final IRegistry<BiomeBase> k;
|
||||||
|
private final boolean isSingleRegistry;
|
||||||
|
|
||||||
|
public FastWorldChunkManagerOverworld(long seed, boolean legacyBiomeInitLayer, boolean largeBiomes, IRegistry<BiomeBase> biomeRegistry) {
|
||||||
|
super(biomeRegistry.g().collect(Collectors.toList()));
|
||||||
|
this.k = biomeRegistry;
|
||||||
|
this.isSingleRegistry = biomeRegistry.d().size() == 1;
|
||||||
|
this.genLayer = GenLayers.a(seed, legacyBiomeInitLayer, largeBiomes ? 6 : 4, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Codec<? extends WorldChunkManager> a() {
|
||||||
|
return WorldChunkManagerOverworld.e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeBase getBiome(int i, int i1, int i2) {
|
||||||
|
if (this.isSingleRegistry) {
|
||||||
|
return this.k.fromId(0);
|
||||||
|
}
|
||||||
|
return this.genLayer.a(this.k, i, i2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
private static class FastWorldGenContextArea implements AreaContextTransformed<FastAreaLazy> {
|
||||||
|
|
||||||
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();
|
||||||
|
@ -242,7 +242,7 @@ public class Fawe {
|
|||||||
String dateString = br.readLine();
|
String dateString = br.readLine();
|
||||||
br.close();
|
br.close();
|
||||||
this.version = FaweVersion.tryParse(versionString, commitString, dateString);
|
this.version = FaweVersion.tryParse(versionString, commitString, dateString);
|
||||||
Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toGMTString();
|
Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toString();
|
||||||
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.16/" + version.build;
|
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.16/" + version.build;
|
||||||
Settings.IMP.COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash);
|
Settings.IMP.COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
@ -60,6 +60,12 @@ public interface IChunkSet extends IBlocks, OutputExtent {
|
|||||||
|
|
||||||
Set<UUID> getEntityRemoves();
|
Set<UUID> getEntityRemoves();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will return only biomes SET to the EXTENT or QUEUE. This will NOT return the current biomes in the world.
|
||||||
|
* This is used for history purposes.
|
||||||
|
*
|
||||||
|
* @return Array of biomes set
|
||||||
|
*/
|
||||||
BiomeType[] getBiomes();
|
BiomeType[] getBiomes();
|
||||||
|
|
||||||
default boolean hasBiomes() {
|
default boolean hasBiomes() {
|
||||||
|
@ -57,7 +57,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return biomes[(z << 4) | x];
|
return biomes[y << 2 | z & 12 | x >> 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,9 +88,9 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
biomes = new BiomeType[256];
|
biomes = new BiomeType[1024];
|
||||||
}
|
}
|
||||||
biomes[x + (z << 4)] = biome;
|
biomes[y << 2 | z & 12 | x >> 2] = biome;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,11 +159,13 @@ public class FallbackChunkGet implements IChunkGet {
|
|||||||
}
|
}
|
||||||
BiomeType[] biomes = set.getBiomes();
|
BiomeType[] biomes = set.getBiomes();
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
for (int z = 0, i = 0; z < 16; z++) {
|
for (int y = 0, i = 0; y < 64; y++) {
|
||||||
for (int x = 0; x < 16; x++, i++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
BiomeType biome = biomes[i];
|
for (int x = 0; x < 4; x++, i++) {
|
||||||
if (biome != null) {
|
BiomeType biome = biomes[i];
|
||||||
extent.setBiome(bx + x, 0, bz + z, biome);
|
if (biome != null) {
|
||||||
|
extent.setBiome(bx + (x << 2), y << 2, bz + (z << 2), biome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,8 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeType[] getBiomes() {
|
public BiomeType[] getBiomes() {
|
||||||
return delegate.set(this).getBiomes(); // TODO return get?
|
// Uses set as this method is only used to retrieve biomes that have been set to the extent/chunk.
|
||||||
|
return delegate.set(this).getBiomes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public char[][] getLight() {
|
@Override public char[][] getLight() {
|
||||||
@ -218,8 +219,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y,
|
public BaseBlock getFullBlock(ChunkHolder chunk, int x, int y, int z) {
|
||||||
int z) {
|
|
||||||
return chunk.chunkExisting.getFullBlock(x, y, z);
|
return chunk.chunkExisting.getFullBlock(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@ public class Settings extends Config {
|
|||||||
"fawe.<plugin> permission. See the Permissions page for supported region plugins."
|
"fawe.<plugin> permission. See the Permissions page for supported region plugins."
|
||||||
})
|
})
|
||||||
public boolean REGION_RESTRICTIONS = true;
|
public boolean REGION_RESTRICTIONS = true;
|
||||||
@Comment("FAWE will skip chunks when there's not enough memory available")
|
|
||||||
public boolean PREVENT_CRASHES = false;
|
|
||||||
@Comment({
|
@Comment({
|
||||||
"FAWE will cancel non admin edits when memory consumption exceeds this %",
|
"FAWE will cancel non admin edits when memory consumption exceeds this %",
|
||||||
" - Bypass with `/wea` or `//fast` or `fawe.bypass`",
|
" - Bypass with `/wea` or `//fast` or `fawe.bypass`",
|
||||||
@ -80,9 +78,6 @@ public class Settings extends Config {
|
|||||||
"Specific aspects can be turned on and off further below"
|
"Specific aspects can be turned on and off further below"
|
||||||
})
|
})
|
||||||
public boolean PLOTSQUARED_HOOK = true;
|
public boolean PLOTSQUARED_HOOK = true;
|
||||||
@Comment({"Send anonymous FAWE statistics to https://bstats.org/.",
|
|
||||||
"Please keep this setting enabled. It helps us identifying which parts of FAWE are used the most to organize future updates better."})
|
|
||||||
public boolean BSTATS = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("Paths for various directories")
|
@Comment("Paths for various directories")
|
||||||
|
@ -50,7 +50,7 @@ public class MCAChunk implements IChunk {
|
|||||||
public final boolean[] hasSections = new boolean[16];
|
public final boolean[] hasSections = new boolean[16];
|
||||||
|
|
||||||
public boolean hasBiomes = false;
|
public boolean hasBiomes = false;
|
||||||
public final BiomeType[] biomes = new BiomeType[256];
|
public final BiomeType[] biomes = new BiomeType[1024];
|
||||||
|
|
||||||
public final char[] blocks = new char[65536];
|
public final char[] blocks = new char[65536];
|
||||||
|
|
||||||
@ -481,7 +481,7 @@ public class MCAChunk implements IChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeType getBiomeType(int x, int y, int z) {
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
return this.biomes[(z << 4) | x];
|
return this.biomes[y << 2 | z & 12 | x >> 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -505,7 +505,7 @@ public class MCAChunk implements IChunk {
|
|||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
setModified();
|
setModified();
|
||||||
biomes[x + (z << 4)] = biome; //TODO Support 3D Biomes
|
biomes[y << 2 | z & 12 | x >> 2] = biome;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
|||||||
public boolean setBiome(BlockVector3 position, BiomeType newBiome) {
|
public boolean setBiome(BlockVector3 position, BiomeType newBiome) {
|
||||||
BiomeType oldBiome = this.getBiome(position);
|
BiomeType oldBiome = this.getBiome(position);
|
||||||
if (oldBiome.getId() != newBiome.getId()) {
|
if (oldBiome.getId() != newBiome.getId()) {
|
||||||
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockZ(), oldBiome, newBiome);
|
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockY(), position.getBlockZ(), oldBiome, newBiome);
|
||||||
return getExtent().setBiome(position, newBiome);
|
return getExtent().setBiome(position, newBiome);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -109,7 +109,7 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
|||||||
public boolean setBiome(int x, int y, int z, BiomeType newBiome) {
|
public boolean setBiome(int x, int y, int z, BiomeType newBiome) {
|
||||||
BiomeType oldBiome = this.getBiome(BlockVector3.at(x, y, z));
|
BiomeType oldBiome = this.getBiome(BlockVector3.at(x, y, z));
|
||||||
if (oldBiome.getId() != newBiome.getId()) {
|
if (oldBiome.getId() != newBiome.getId()) {
|
||||||
this.changeSet.addBiomeChange(x, z, oldBiome, newBiome);
|
this.changeSet.addBiomeChange(x, y, z, oldBiome, newBiome);
|
||||||
return getExtent().setBiome(x, y, z, newBiome);
|
return getExtent().setBiome(x, y, z, newBiome);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -46,7 +46,7 @@ public class NullChangeSet extends AbstractChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) {
|
public void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,12 @@ public class VisualExtent extends AbstractDelegateExtent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
|
// Do nothing
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
IQueueExtent queue = (IQueueExtent) getExtent();
|
IQueueExtent queue = (IQueueExtent) getExtent();
|
||||||
queue.cancel();
|
queue.cancel();
|
||||||
|
@ -4,11 +4,12 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.history.UndoContext;
|
import com.sk89q.worldedit.history.UndoContext;
|
||||||
import com.sk89q.worldedit.history.change.Change;
|
import com.sk89q.worldedit.history.change.Change;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||||
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
|
|
||||||
public class MutableBiomeChange implements Change {
|
public class MutableBiomeChange implements Change {
|
||||||
|
|
||||||
private MutableBlockVector2 mutable = new MutableBlockVector2();
|
private final MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||||
private int from;
|
private int from;
|
||||||
private int to;
|
private int to;
|
||||||
|
|
||||||
@ -17,8 +18,8 @@ public class MutableBiomeChange implements Change {
|
|||||||
this.to = 0;
|
this.to = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBiome(int x, int z, int from, int to) {
|
public void setBiome(int x, int y, int z, int from, int to) {
|
||||||
mutable.setComponents(x, z);
|
mutable.setComponents(x, y, z);
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
}
|
}
|
||||||
|
@ -188,13 +188,15 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
|
|
||||||
BiomeType[] biomes = set.getBiomes();
|
BiomeType[] biomes = set.getBiomes();
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
for (int z = 0, index = 0; z < 16; z++) {
|
for (int y = 0, index = 0; y < 64; y++) {
|
||||||
for (int x = 0; x < 16; x++, index++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
BiomeType newBiome = biomes[index];
|
for (int x = 0; x < 4; x++, index++) {
|
||||||
if (newBiome != null) {
|
BiomeType newBiome = biomes[index];
|
||||||
BiomeType oldBiome = get.getBiomeType(x, 0, z);
|
if (newBiome != null) {
|
||||||
if (oldBiome != newBiome) {
|
BiomeType oldBiome = get.getBiomeType(x, y, z);
|
||||||
addBiomeChange(bx + x, bz + z, oldBiome, newBiome);
|
if (oldBiome != newBiome) {
|
||||||
|
addBiomeChange(bx + (x << 2), y << 2,bz + (z << 2), oldBiome, newBiome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +218,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
|
|
||||||
public abstract void addEntityCreate(CompoundTag tag);
|
public abstract void addEntityCreate(CompoundTag tag);
|
||||||
|
|
||||||
public abstract void addBiomeChange(int x, int z, BiomeType from, BiomeType to);
|
public abstract void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to);
|
||||||
|
|
||||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||||
return getIterator(redo);
|
return getIterator(redo);
|
||||||
|
@ -69,8 +69,8 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) {
|
public void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to) {
|
||||||
parent.addBiomeChange(x, z, from, to);
|
parent.addBiomeChange(x, y, z, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,7 +68,7 @@ public class CFIChangeSet extends AbstractChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) {
|
public void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to) {
|
||||||
throw new UnsupportedOperationException("Only CFI operations are supported");
|
throw new UnsupportedOperationException("Only CFI operations are supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBiomeChange(int x, int z, BiomeType from, BiomeType to) {
|
public void addBiomeChange(int x, int y, int z, BiomeType from, BiomeType to) {
|
||||||
blockSize++;
|
blockSize++;
|
||||||
try {
|
try {
|
||||||
FaweOutputStream os = getBiomeOS();
|
FaweOutputStream os = getBiomeOS();
|
||||||
@ -333,6 +333,7 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
os.write((byte) (z >> 16));
|
os.write((byte) (z >> 16));
|
||||||
os.write((byte) (z >> 8));
|
os.write((byte) (z >> 8));
|
||||||
os.write((byte) (z));
|
os.write((byte) (z));
|
||||||
|
os.write((byte) (y));
|
||||||
os.writeVarInt(from.getInternalId());
|
os.writeVarInt(from.getInternalId());
|
||||||
os.writeVarInt(to.getInternalId());
|
os.writeVarInt(to.getInternalId());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -462,9 +463,10 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet {
|
|||||||
if (int1 != -1) {
|
if (int1 != -1) {
|
||||||
int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
||||||
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read());
|
||||||
|
int y = is.read();
|
||||||
int from = is.readVarInt();
|
int from = is.readVarInt();
|
||||||
int to = is.readVarInt();
|
int to = is.readVarInt();
|
||||||
change.setBiome(x, z, from, to);
|
change.setBiome(x, y, z, from, to);
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
} catch (EOFException ignored) {
|
} catch (EOFException ignored) {
|
||||||
|
@ -185,7 +185,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
setBiome(getIndex(x, y, z), biome);
|
setBiome(getIndex(x, 0, z), biome);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -56,7 +55,7 @@ public class MultiTransform extends RandomTransform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
// don't use streams for each block place, it'd be incredibly slow
|
// don't use streams for each block place, it'd be incredibly slow
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for (AbstractDelegateExtent extent : extents) {
|
for (AbstractDelegateExtent extent : extents) {
|
||||||
|
@ -2,9 +2,7 @@ package com.boydti.fawe.object.extent;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
@ -13,7 +11,6 @@ public class OffsetExtent extends ResettableExtent {
|
|||||||
private final int dx;
|
private final int dx;
|
||||||
private final int dy;
|
private final int dy;
|
||||||
private final int dz;
|
private final int dz;
|
||||||
private transient MutableBlockVector2 mutable = new MutableBlockVector2();
|
|
||||||
|
|
||||||
public OffsetExtent(Extent parent, int dx, int dy, int dz) {
|
public OffsetExtent(Extent parent, int dx, int dy, int dz) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -23,9 +20,9 @@ public class OffsetExtent extends ResettableExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
return getExtent()
|
return getExtent()
|
||||||
.setBiome(mutable.setComponents(position.getBlockX() + dx, position.getBlockZ() + dz),
|
.setBiome(position.getBlockX() + dx, position.getBlockY() + dy, position.getBlockZ() + dz,
|
||||||
biome);
|
biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +43,4 @@ public class OffsetExtent extends ResettableExtent {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
|
return getExtent().setBlock(x + dx, y + dy, z + dz, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResettableExtent setExtent(Extent extent) {
|
|
||||||
mutable = new MutableBlockVector2();
|
|
||||||
return super.setExtent(extent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
|||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -100,7 +99,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
if (!limit.MAX_CHANGES()) {
|
if (!limit.MAX_CHANGES()) {
|
||||||
WEManager.IMP.cancelEditSafe(this, FaweCache.MAX_CHANGES);
|
WEManager.IMP.cancelEditSafe(this, FaweCache.MAX_CHANGES);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,9 +2,7 @@ package com.boydti.fawe.object.extent;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
@ -16,7 +14,6 @@ public class RandomOffsetTransform extends ResettableExtent {
|
|||||||
private final int dy;
|
private final int dy;
|
||||||
private final int dz;
|
private final int dz;
|
||||||
private transient SplittableRandom random;
|
private transient SplittableRandom random;
|
||||||
private transient MutableBlockVector2 mutable = new MutableBlockVector2();
|
|
||||||
|
|
||||||
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
|
public RandomOffsetTransform(Extent parent, int dx, int dy, int dz) {
|
||||||
super(parent);
|
super(parent);
|
||||||
@ -27,10 +24,11 @@ public class RandomOffsetTransform extends ResettableExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 pos, BiomeType biome) {
|
public boolean setBiome(BlockVector3 pos, BiomeType biome) {
|
||||||
int x = pos.getBlockX() + random.nextInt(1 + (dx << 1)) - dx;
|
int x = pos.getBlockX() + random.nextInt(1 + (dx << 1)) - dx;
|
||||||
|
int y = pos.getBlockY() + random.nextInt(1 + (dy << 1)) - dy;
|
||||||
int z = pos.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz;
|
int z = pos.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz;
|
||||||
return getExtent().setBiome(mutable.setComponents(x, z), biome);
|
return getExtent().setBiome(x, y, z, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -54,7 +52,6 @@ public class RandomOffsetTransform extends ResettableExtent {
|
|||||||
@Override
|
@Override
|
||||||
public ResettableExtent setExtent(Extent extent) {
|
public ResettableExtent setExtent(Extent extent) {
|
||||||
random = new SplittableRandom();
|
random = new SplittableRandom();
|
||||||
mutable = new MutableBlockVector2();
|
|
||||||
return super.setExtent(extent);
|
return super.setExtent(extent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
@ -82,17 +81,20 @@ public class ScaleTransform extends ResettableExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
MutableBlockVector3 pos = new MutableBlockVector3(
|
MutableBlockVector3 pos = new MutableBlockVector3(getPos(position));
|
||||||
getPos(position.getBlockX(), 0, position.getBlockZ()));
|
|
||||||
double sx = pos.getX();
|
double sx = pos.getX();
|
||||||
|
double sy = pos.getY();
|
||||||
double sz = pos.getZ();
|
double sz = pos.getZ();
|
||||||
double ex = pos.getX() + dx;
|
double ex = sx + dx;
|
||||||
double ez = pos.getZ() + dz;
|
double ey = Math.min(maxy, sy + dy);
|
||||||
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
|
double ez = sz + dz;
|
||||||
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
|
for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) {
|
||||||
result |= super.setBiome(pos.toBlockVector2(), biome);
|
for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) {
|
||||||
|
for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) {
|
||||||
|
result |= super.setBiome(pos, biome);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -52,7 +52,7 @@ public abstract class SelectTransform extends ResettableExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
return getExtent(position).setBiome(position, biome);
|
return getExtent(position).setBiome(position, biome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,6 +232,7 @@ public final class IncendoPaster implements Paster {
|
|||||||
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
||||||
b.append("Uptime: ").append(TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS))
|
b.append("Uptime: ").append(TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS))
|
||||||
.append(" minutes").append('\n');
|
.append(" minutes").append('\n');
|
||||||
|
b.append("JVM Flags: ").append(rb.getInputArguments()).append('\n');
|
||||||
b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024).append(" MB").append('\n');
|
b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024).append(" MB").append('\n');
|
||||||
b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024).append(" MB").append('\n');
|
b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024).append(" MB").append('\n');
|
||||||
b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024).append(" MB").append('\n');
|
b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024).append(" MB").append('\n');
|
||||||
|
@ -29,6 +29,7 @@ import com.sk89q.worldedit.util.SideEffect;
|
|||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.util.TreeGenerator;
|
import com.sk89q.worldedit.util.TreeGenerator;
|
||||||
import com.sk89q.worldedit.world.AbstractWorld;
|
import com.sk89q.worldedit.world.AbstractWorld;
|
||||||
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
@ -242,6 +243,11 @@ public class WorldWrapper extends AbstractWorld {
|
|||||||
return parent.regenerate(region, session);
|
return parent.regenerate(region, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean regenerate(Region region, Extent extent, RegenOptions options) {
|
||||||
|
return parent.regenerate(region, extent, options);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
|
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
|
||||||
return TaskManager.IMP.sync(() -> {
|
return TaskManager.IMP.sync(() -> {
|
||||||
|
@ -63,7 +63,9 @@ import com.sk89q.worldedit.util.Location;
|
|||||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||||
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import org.enginehub.piston.annotation.Command;
|
import org.enginehub.piston.annotation.Command;
|
||||||
@ -609,15 +611,26 @@ public class RegionCommands {
|
|||||||
@CommandPermissions("worldedit.regen")
|
@CommandPermissions("worldedit.regen")
|
||||||
@Logging(REGION)
|
@Logging(REGION)
|
||||||
@Confirm(Confirm.Processor.REGION)
|
@Confirm(Confirm.Processor.REGION)
|
||||||
public void regenerateChunk(Actor actor, World world, LocalSession session, EditSession editSession,
|
void regenerate(Actor actor, World world, LocalSession session, EditSession editSession,
|
||||||
@Selection Region region) throws WorldEditException {
|
@Selection Region region,
|
||||||
|
@Arg(desc = "The seed to regenerate with, otherwise uses world seed", def = "")
|
||||||
|
Long seed,
|
||||||
|
@Switch(name = 'b', desc = "Regenerate biomes as well")
|
||||||
|
boolean regenBiomes,
|
||||||
|
@Arg(desc = "Biome to apply for this regeneration (only works in overworld)", def = "")
|
||||||
|
BiomeType biomeType) throws WorldEditException {
|
||||||
Mask mask = session.getMask();
|
Mask mask = session.getMask();
|
||||||
boolean success;
|
boolean success;
|
||||||
try {
|
try {
|
||||||
session.setMask((Mask) null);
|
session.setMask(null);
|
||||||
session.setSourceMask((Mask) null);
|
session.setSourceMask(null);
|
||||||
actor.printInfo(TranslatableComponent.of("fawe.regen.time"));
|
actor.printInfo(TranslatableComponent.of("fawe.regen.time"));
|
||||||
success = world.regenerate(region, editSession);
|
RegenOptions options = RegenOptions.builder()
|
||||||
|
.seed(seed)
|
||||||
|
.regenBiomes(regenBiomes)
|
||||||
|
.biomeType(biomeType)
|
||||||
|
.build();
|
||||||
|
success = world.regenerate(region, editSession, options);
|
||||||
} finally {
|
} finally {
|
||||||
session.setMask(mask);
|
session.setMask(mask);
|
||||||
session.setSourceMask(mask);
|
session.setSourceMask(mask);
|
||||||
|
@ -52,7 +52,8 @@ public @interface Confirm {
|
|||||||
* (long) value;
|
* (long) value;
|
||||||
long max = 2 << 18;
|
long max = 2 << 18;
|
||||||
if (max != -1 && area > max) {
|
if (max != -1 && area > max) {
|
||||||
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.region", pos1, pos2, getArgs(context)));
|
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.region",
|
||||||
|
pos1, pos2, getArgs(context), region.getHeight() * area));
|
||||||
return confirm(actor, context);
|
return confirm(actor, context);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -63,8 +64,9 @@ public @interface Confirm {
|
|||||||
public boolean passes(Actor actor, InjectedValueAccess context, double value) {
|
public boolean passes(Actor actor, InjectedValueAccess context, double value) {
|
||||||
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
||||||
if (max != -1 && value > max) {
|
if (max != -1 && value > max) {
|
||||||
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.region", value, max, getArgs(context)));
|
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.radius",
|
||||||
return Processor.confirm(actor, context);
|
value, max, getArgs(context)));
|
||||||
|
return confirm(actor, context);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -74,8 +76,9 @@ public @interface Confirm {
|
|||||||
public boolean passes(Actor actor, InjectedValueAccess context, double value) {
|
public boolean passes(Actor actor, InjectedValueAccess context, double value) {
|
||||||
int max = 50; //TODO configurable, get Key.of(Method.class) @Limit
|
int max = 50; //TODO configurable, get Key.of(Method.class) @Limit
|
||||||
if (max != -1 && value > max) {
|
if (max != -1 && value > max) {
|
||||||
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.region", value, max, getArgs(context)));
|
actor.print(Caption.of("fawe.cancel.worldedit.cancel.reason.confirm.limit",
|
||||||
return Processor.confirm(actor, context);
|
value, max, getArgs(context)));
|
||||||
|
return confirm(actor, context);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ 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.OffsetMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.ROCAngleMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.ROCAngleMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
|
||||||
|
import com.sk89q.worldedit.extension.factory.parser.mask.RichOffsetMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.SimplexMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.SimplexMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.SurfaceMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.SurfaceMaskParser;
|
||||||
@ -97,6 +98,7 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
|||||||
register(new FalseMaskParser(worldEdit));
|
register(new FalseMaskParser(worldEdit));
|
||||||
register(new LiquidMaskParser(worldEdit));
|
register(new LiquidMaskParser(worldEdit));
|
||||||
//register(new RadiusMaskParser(worldEdit)); TODO: Adapt to work with FAWE's Chunk I/O
|
//register(new RadiusMaskParser(worldEdit)); TODO: Adapt to work with FAWE's Chunk I/O
|
||||||
|
register(new RichOffsetMaskParser(worldEdit));
|
||||||
register(new ROCAngleMaskParser(worldEdit));
|
register(new ROCAngleMaskParser(worldEdit));
|
||||||
register(new SimplexMaskParser(worldEdit));
|
register(new SimplexMaskParser(worldEdit));
|
||||||
register(new SurfaceMaskParser(worldEdit));
|
register(new SurfaceMaskParser(worldEdit));
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||||
|
import com.sk89q.worldedit.extension.factory.parser.RichParser;
|
||||||
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||||
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
|
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class RichOffsetMaskParser extends RichParser<Mask> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||||
|
*
|
||||||
|
* @param worldEdit the worldedit instance.
|
||||||
|
*/
|
||||||
|
public RichOffsetMaskParser(WorldEdit worldEdit) {
|
||||||
|
super(worldEdit, "#offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||||
|
if (index < 3) {
|
||||||
|
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||||
|
}
|
||||||
|
if (index == 3) {
|
||||||
|
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||||
|
if (arguments.length != 4) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int x = Integer.parseInt(arguments[0]);
|
||||||
|
int y = Integer.parseInt(arguments[1]);
|
||||||
|
int z = Integer.parseInt(arguments[2]);
|
||||||
|
Mask submask = worldEdit.getMaskFactory().parseFromInput(arguments[3], context);
|
||||||
|
OffsetMask offsetMask = new OffsetMask(submask, BlockVector3.at(x, y, z));
|
||||||
|
return new MaskIntersection(offsetMask, Masks.negate(submask));
|
||||||
|
}
|
||||||
|
}
|
@ -192,7 +192,7 @@ public interface Actor extends Identifiable, SessionOwner, Subject, MapMetadatab
|
|||||||
if (confirm == null) {
|
if (confirm == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
queueAction(confirm::signal);
|
confirm.signal();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
|
|||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
@ -93,11 +92,6 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce
|
|||||||
return this.mask.test(location) && super.setBlock(location, block);
|
return this.mask.test(location) && super.setBlock(location, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
|
||||||
return this.mask.test(position.toBlockVector3()) && super.setBiome(position, biome);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
return this.mask.test(BlockVector3.at(x, y, z)) && super.setBiome(x, y, z, biome);
|
return this.mask.test(BlockVector3.at(x, y, z)) && super.setBiome(x, y, z, biome);
|
||||||
|
@ -94,7 +94,11 @@ public interface OutputExtent {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default boolean setBiome(BlockVector2 position, BiomeType biome) {
|
default boolean setBiome(BlockVector2 position, BiomeType biome) {
|
||||||
return setBiome(position.toBlockVector3(), biome);
|
boolean result = false;
|
||||||
|
for (int y = 0; y < 256; y ++) {
|
||||||
|
result |= setBiome(position.toBlockVector3().mutY(y), biome);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonAbstractForCompatibility(
|
@NonAbstractForCompatibility(
|
||||||
|
@ -10,7 +10,6 @@ import com.sk89q.worldedit.function.generator.Resource;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
@ -199,7 +198,7 @@ public class PassthroughExtent extends AbstractDelegateExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
return getExtent().setBiome(position, biome);
|
return getExtent().setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +71,9 @@ public class ChunkLoadingExtent extends AbstractDelegateExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
world.checkLoadedChunk(position.toBlockVector3());
|
world.checkLoadedChunk(position);
|
||||||
}
|
}
|
||||||
return super.setBiome(position, biome);
|
return super.setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import com.sk89q.worldedit.entity.Entity;
|
|||||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -88,7 +87,7 @@ public class WatchdogTickingExtent extends AbstractDelegateExtent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||||
onOperation();
|
onOperation();
|
||||||
return super.setBiome(position, biome);
|
return super.setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.internal.command;
|
package com.sk89q.worldedit.internal.command;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.sk89q.worldedit.command.util.annotation.Confirm;
|
import com.sk89q.worldedit.command.util.annotation.Confirm;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
@ -46,6 +47,10 @@ public class ConfirmHandler implements CommandCallListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Actor actor = actorOpt.get();
|
Actor actor = actorOpt.get();
|
||||||
|
// don't check confirmation if actor doesn't need to confirm
|
||||||
|
if (!Settings.IMP.getLimit(actor).CONFIRM_LARGE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!confirmAnnotation.value().passes(actor, parameters, 1)) {
|
if (!confirmAnnotation.value().passes(actor, parameters, 1)) {
|
||||||
throw new StopExecutionException(TextComponent.empty());
|
throw new StopExecutionException(TextComponent.empty());
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.world;
|
|||||||
import com.google.auto.value.AutoValue;
|
import com.google.auto.value.AutoValue;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
|
||||||
import java.util.OptionalLong;
|
import java.util.OptionalLong;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -38,7 +39,7 @@ public abstract class RegenOptions {
|
|||||||
* @return the builder
|
* @return the builder
|
||||||
*/
|
*/
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new AutoValue_RegenOptions.Builder().seed(OptionalLong.empty()).regenBiomes(false);
|
return new AutoValue_RegenOptions.Builder().seed(OptionalLong.empty()).regenBiomes(false).biomeType(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoValue.Builder
|
@AutoValue.Builder
|
||||||
@ -69,6 +70,13 @@ public abstract class RegenOptions {
|
|||||||
*/
|
*/
|
||||||
public abstract Builder regenBiomes(boolean regenBiomes);
|
public abstract Builder regenBiomes(boolean regenBiomes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the {@code BiomeType} the regenerator should use for regeneration. Defaults to {@code null}.
|
||||||
|
* @param biomeType the {@code BiomeType} to be used for regeneration
|
||||||
|
* @return this builder
|
||||||
|
*/
|
||||||
|
public abstract Builder biomeType(@Nullable BiomeType biomeType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the options object.
|
* Build the options object.
|
||||||
*
|
*
|
||||||
@ -99,4 +107,10 @@ public abstract class RegenOptions {
|
|||||||
return isRegenBiomes();
|
return isRegenBiomes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable public abstract BiomeType getBiomeType();
|
||||||
|
|
||||||
|
public boolean hasBiomeType() {
|
||||||
|
return getBiomeType() != null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,8 @@
|
|||||||
"fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.",
|
"fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.",
|
||||||
"fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {2}",
|
"fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {2}",
|
||||||
"fawe.cancel.worldedit.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}",
|
"fawe.cancel.worldedit.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}",
|
||||||
|
"fawe.cancel.worldedit.cancel.reason.confirm.radius": "Your radius is large ({0} > {1}). Use //confirm to execute {2}",
|
||||||
|
"fawe.cancel.worldedit.cancel.reason.confirm.limit": "You're exceeding your limit for this action ({0} > {1}). Use //confirm to execute {2}",
|
||||||
"fawe.cancel.worldedit.cancel.reason": "Your WorldEdit action was cancelled: {0}.",
|
"fawe.cancel.worldedit.cancel.reason": "Your WorldEdit action was cancelled: {0}.",
|
||||||
"fawe.cancel.worldedit.cancel.reason.manual": "Manual cancellation",
|
"fawe.cancel.worldedit.cancel.reason.manual": "Manual cancellation",
|
||||||
"fawe.cancel.worldedit.cancel.reason.low.memory": "Low memory",
|
"fawe.cancel.worldedit.cancel.reason.low.memory": "Low memory",
|
||||||
@ -505,6 +507,8 @@
|
|||||||
"worldedit.sideeffect.lighting.description": "Updates block lighting",
|
"worldedit.sideeffect.lighting.description": "Updates block lighting",
|
||||||
"worldedit.sideeffect.neighbors": "Neighbors",
|
"worldedit.sideeffect.neighbors": "Neighbors",
|
||||||
"worldedit.sideeffect.neighbors.description": "Notifies nearby blocks of changes",
|
"worldedit.sideeffect.neighbors.description": "Notifies nearby blocks of changes",
|
||||||
|
"worldedit.sideeffect.update": "Update",
|
||||||
|
"worldedit.sideeffect.update.description": "Notifies the changed block",
|
||||||
"worldedit.sideeffect.validation": "Validation",
|
"worldedit.sideeffect.validation": "Validation",
|
||||||
"worldedit.sideeffect.validation.description": "Validates and fixes inconsistent world state, such as disconnected blocks",
|
"worldedit.sideeffect.validation.description": "Validates and fixes inconsistent world state, such as disconnected blocks",
|
||||||
"worldedit.sideeffect.entity_ai": "Entity AI",
|
"worldedit.sideeffect.entity_ai": "Entity AI",
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren