Merge pull request #707 from IronApollo/biome-regen

Implement biome-specific regen
This commit is contained in:
NotMyFault
2020-10-22 10:57:49 +02:00
committed by GitHub
7 changed files with 177 additions and 23 deletions

View File

@ -11,6 +11,7 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
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.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@ -266,9 +267,13 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
//Setting Blocks
long start = System.currentTimeMillis();
boolean genbiomes = options.shouldRegenBiomes();
boolean hasBiome = options.hasBiomeType();
BiomeType biome = options.getBiomeType();
for (BlockVector3 vec : region) {
target.setBlock(vec, source.getBlock(vec));
if (genbiomes) {
if (hasBiome) {
target.setBiome(vec, biome);
} else if (genbiomes) {
target.setBiome(vec, source.getBiome(vec));
}
// realExtent.setSkyLight(vec, extent.getSkyLight(vec));

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IChunkCache;
import com.boydti.fawe.beta.IChunkGet;
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.sk89q.worldedit.bukkit.adapter.Regenerator;
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.LightEngineThreaded;
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.NBTTagCompound;
import net.minecraft.server.v1_15_R1.NoiseGeneratorPerlin;
@ -182,6 +184,16 @@ public class Regen_v1_15_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
@Override
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();
freshNMSWorld.savingDisabled = true;
removeWorldFromWorldsMap();
@ -358,15 +370,34 @@ public class Regen_v1_15_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
//init new WorldChunkManagerOverworld
BiomeLayoutOverworldConfiguration biomeconfig = new BiomeLayoutOverworldConfiguration(freshNMSWorld.getWorldData())
.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)));
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;
}
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 final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();

View File

@ -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.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.Lifecycle;
import com.sk89q.worldedit.bukkit.adapter.Regenerator;
@ -17,6 +18,7 @@ import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
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.IChunkAccess;
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.LinearCongruentialGenerator;
import net.minecraft.server.v1_16_R1.MinecraftKey;
import net.minecraft.server.v1_16_R1.MinecraftServer;
import net.minecraft.server.v1_16_R1.NBTBase;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.NoiseGeneratorPerlin;
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.World;
import net.minecraft.server.v1_16_R1.WorldChunkManager;
@ -201,6 +202,16 @@ public class Regen_v1_16_R1 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
@Override
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();
freshNMSWorld.savingDisabled = true;
removeWorldFromWorldsMap();
@ -398,16 +409,41 @@ public class Regen_v1_16_R1 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
//init new WorldChunkManagerOverworld
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
boolean largebiomes = largeBiomesField.getBoolean(chunkManager);
chunkManager = new WorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largebiomes);
boolean largeBiomes = largeBiomesField.getBoolean(chunkManager);
//replace genLayer
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));
AreaFactory<FastAreaLazy> factory = (AreaFactory<FastAreaLazy>) initAreaFactoryMethod.invoke(null, legacyBiomeInitLayer, largeBiomes ? 6 : 4, 4, (LongFunction) (l -> new FastWorldGenContextArea(seed, l)));
if (options.hasBiomeType()) {
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;
}
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 final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();

View File

@ -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.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.Lifecycle;
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.LongFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.server.v1_16_R2.Area;
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.LightEngineThreaded;
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.NBTBase;
import net.minecraft.server.v1_16_R2.NBTTagCompound;
import net.minecraft.server.v1_16_R2.NoiseGeneratorPerlin;
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.ResourceKey;
import net.minecraft.server.v1_16_R2.World;
@ -202,6 +207,16 @@ public class Regen_v1_16_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
@Override
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();
freshNMSWorld.savingDisabled = true;
removeWorldFromWorldsMap();
@ -395,8 +410,6 @@ public class Regen_v1_16_R2 extends Regenerator<IChunkAccess, ProtoChunk, Chunk,
largeBiomesField.setAccessible(true);
Field biomeRegistryField = WorldChunkManagerOverworld.class.getDeclaredField("k");
biomeRegistryField.setAccessible(true);
Field genLayerField = WorldChunkManagerOverworld.class.getDeclaredField("f");
genLayerField.setAccessible(true);
Field areaLazyField = GenLayer.class.getDeclaredField("b");
areaLazyField.setAccessible(true);
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
boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(chunkManager);
boolean largebiomes = largeBiomesField.getBoolean(chunkManager);
IRegistry<BiomeBase> biomeRegistry = (IRegistry<BiomeBase>) biomeRegistryField.get(chunkManager);
chunkManager = new WorldChunkManagerOverworld(seed, legacyBiomeInitLayer, largebiomes, biomeRegistry);
IRegistry<BiomeBase> biomeRegistrynms = (IRegistry<BiomeBase>) biomeRegistryField.get(chunkManager);
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
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;
}
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 final ConcurrentHashMap<Long, Integer> sharedAreaMap = new ConcurrentHashMap<>();