mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 01:37:37 +00:00
Implement generation of biome decorations to //regen <biome> and add option for a random seed to be used (#1819)
This commit is contained in:
parent
692a010c39
commit
dac3610bcf
@ -11,7 +11,6 @@ import com.mojang.datafixers.util.Either;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.PaperweightAdapter;
|
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightGetBlocks;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightGetBlocks;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
@ -38,6 +37,7 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
|||||||
import net.minecraft.world.level.LevelSettings;
|
import net.minecraft.world.level.LevelSettings;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||||
import net.minecraft.world.level.biome.OverworldBiomeSource;
|
import net.minecraft.world.level.biome.OverworldBiomeSource;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
@ -67,6 +67,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
|
import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
|
import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -213,6 +214,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||||
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||||
|
|
||||||
|
BiomeProvider biomeProvider = getBiomeProvider();
|
||||||
|
|
||||||
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||||
PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData();
|
PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData();
|
||||||
|
|
||||||
@ -246,7 +249,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
false,
|
false,
|
||||||
environment,
|
environment,
|
||||||
generator,
|
generator,
|
||||||
originalBukkitWorld.getBiomeProvider()
|
biomeProvider
|
||||||
) {
|
) {
|
||||||
private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(
|
private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(
|
||||||
options
|
options
|
||||||
@ -280,9 +283,16 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
} else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator) {
|
} else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator) {
|
||||||
Supplier<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Supplier<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
Supplier<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Supplier<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
||||||
.get(originalChunkProvider.getGenerator());
|
.get(originalChunkProvider.getGenerator());
|
||||||
BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource();
|
BiomeSource biomeSource;
|
||||||
if (biomeSource instanceof OverworldBiomeSource) {
|
if (options.hasBiomeType()) {
|
||||||
biomeSource = fastOverworldBiomeSource(biomeSource);
|
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(options
|
||||||
|
.getBiomeType()
|
||||||
|
.getId())));
|
||||||
|
} else {
|
||||||
|
biomeSource = originalChunkProvider.getGenerator().getBiomeSource();
|
||||||
|
if (biomeSource instanceof OverworldBiomeSource) {
|
||||||
|
biomeSource = fastOverworldBiomeSource(biomeSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chunkGenerator = new NoiseBasedChunkGenerator(biomeSource, seed, generatorSettingBaseSupplier);
|
chunkGenerator = new NoiseBasedChunkGenerator(biomeSource, seed, generatorSettingBaseSupplier);
|
||||||
} else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator) {
|
} else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator) {
|
||||||
|
@ -17,6 +17,7 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
||||||
import com.sk89q.worldedit.world.RegenOptions;
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.data.BuiltinRegistries;
|
import net.minecraft.data.BuiltinRegistries;
|
||||||
@ -33,6 +34,7 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
|||||||
import net.minecraft.world.level.LevelSettings;
|
import net.minecraft.world.level.LevelSettings;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@ -46,6 +48,7 @@ import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
|||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
@ -54,6 +57,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator;
|
import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -81,6 +85,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
private static final Field generatorSettingBaseSupplierField;
|
private static final Field generatorSettingBaseSupplierField;
|
||||||
private static final Field delegateField;
|
private static final Field delegateField;
|
||||||
private static final Field chunkSourceField;
|
private static final Field chunkSourceField;
|
||||||
|
private static final Field ringPositionsField;
|
||||||
|
private static final Field hasGeneratedPositionsField;
|
||||||
|
|
||||||
//list of chunk stati in correct order without FULL
|
//list of chunk stati in correct order without FULL
|
||||||
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
||||||
@ -139,6 +145,12 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "K"));
|
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "K"));
|
||||||
chunkSourceField.setAccessible(true);
|
chunkSourceField.setAccessible(true);
|
||||||
|
|
||||||
|
ringPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("ringPositions", "i"));
|
||||||
|
ringPositionsField.setAccessible(true);
|
||||||
|
|
||||||
|
hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "j"));
|
||||||
|
hasGeneratedPositionsField.setAccessible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -198,6 +210,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||||
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||||
|
|
||||||
|
BiomeProvider biomeProvider = getBiomeProvider();
|
||||||
|
|
||||||
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||||
PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData();
|
PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData();
|
||||||
WorldGenSettings originalOpts = levelProperties.worldGenSettings();
|
WorldGenSettings originalOpts = levelProperties.worldGenSettings();
|
||||||
@ -232,7 +246,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
false,
|
false,
|
||||||
environment,
|
environment,
|
||||||
generator,
|
generator,
|
||||||
originalBukkitWorld.getBiomeProvider()
|
biomeProvider
|
||||||
) {
|
) {
|
||||||
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
|
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
||||||
@ -260,22 +274,30 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
|
|
||||||
//generator
|
//generator
|
||||||
if (originalChunkProvider.getGenerator() instanceof FlatLevelSource flatLevelSource) {
|
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
|
||||||
|
if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
|
||||||
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
||||||
chunkGenerator = new FlatLevelSource(originalChunkProvider.getGenerator().structureSets, generatorSettingFlat);
|
chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat);
|
||||||
} else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||||
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier =
|
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier =
|
||||||
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
||||||
.get(originalChunkProvider.getGenerator());
|
.get(originalGenerator);
|
||||||
BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource();
|
BiomeSource biomeSource;
|
||||||
chunkGenerator = new NoiseBasedChunkGenerator(originalChunkProvider.getGenerator().structureSets, noiseBasedChunkGenerator.noises,
|
if (options.hasBiomeType()) {
|
||||||
|
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME
|
||||||
|
.asHolderIdMap()
|
||||||
|
.byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())));
|
||||||
|
} else {
|
||||||
|
biomeSource = originalGenerator.getBiomeSource();
|
||||||
|
}
|
||||||
|
chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, noiseBasedChunkGenerator.noises,
|
||||||
biomeSource, seed,
|
biomeSource, seed,
|
||||||
generatorSettingBaseSupplier
|
generatorSettingBaseSupplier
|
||||||
);
|
);
|
||||||
} else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator customChunkGenerator) {
|
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
|
||||||
chunkGenerator = customChunkGenerator.delegate;
|
chunkGenerator = customChunkGenerator.delegate;
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName());
|
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (generator != null) {
|
if (generator != null) {
|
||||||
@ -283,6 +305,20 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
generateConcurrent = generator.isParallelCapable();
|
generateConcurrent = generator.isParallelCapable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
|
||||||
|
// Optimisation for needless ring position calculation when the seed and biome is the same.
|
||||||
|
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(originalGenerator);
|
||||||
|
if (hasGeneratedPositions) {
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions =
|
||||||
|
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(
|
||||||
|
originalGenerator);
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(ringPositions);
|
||||||
|
ringPositionsField.set(chunkGenerator, copy);
|
||||||
|
hasGeneratedPositionsField.setBoolean(chunkGenerator, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
chunkGenerator.conf = originalServerWorld.spigotConfig;
|
chunkGenerator.conf = originalServerWorld.spigotConfig;
|
||||||
freshChunkProvider = new ServerChunkCache(
|
freshChunkProvider = new ServerChunkCache(
|
||||||
freshWorld,
|
freshWorld,
|
||||||
|
@ -17,6 +17,7 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
||||||
import com.sk89q.worldedit.world.RegenOptions;
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.data.BuiltinRegistries;
|
import net.minecraft.data.BuiltinRegistries;
|
||||||
@ -36,6 +37,7 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
|||||||
import net.minecraft.world.level.LevelSettings;
|
import net.minecraft.world.level.LevelSettings;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
@ -49,6 +51,7 @@ import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
|||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
@ -57,6 +60,7 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.generator.CustomChunkGenerator;
|
import org.bukkit.craftbukkit.v1_19_R1.generator.CustomChunkGenerator;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -84,6 +88,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
private static final Field generatorSettingBaseSupplierField;
|
private static final Field generatorSettingBaseSupplierField;
|
||||||
private static final Field delegateField;
|
private static final Field delegateField;
|
||||||
private static final Field chunkSourceField;
|
private static final Field chunkSourceField;
|
||||||
|
private static final Field ringPositionsField;
|
||||||
|
private static final Field hasGeneratedPositionsField;
|
||||||
|
|
||||||
//list of chunk stati in correct order without FULL
|
//list of chunk stati in correct order without FULL
|
||||||
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
||||||
@ -142,6 +148,12 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "L"));
|
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "L"));
|
||||||
chunkSourceField.setAccessible(true);
|
chunkSourceField.setAccessible(true);
|
||||||
|
|
||||||
|
ringPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("ringPositions", "i"));
|
||||||
|
ringPositionsField.setAccessible(true);
|
||||||
|
|
||||||
|
hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "j"));
|
||||||
|
hasGeneratedPositionsField.setAccessible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -218,6 +230,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
);
|
);
|
||||||
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
||||||
|
|
||||||
|
BiomeProvider biomeProvider = getBiomeProvider();
|
||||||
|
|
||||||
//init world
|
//init world
|
||||||
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
||||||
server,
|
server,
|
||||||
@ -233,7 +247,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
false,
|
false,
|
||||||
environment,
|
environment,
|
||||||
generator,
|
generator,
|
||||||
originalBukkitWorld.getBiomeProvider()
|
biomeProvider
|
||||||
) {
|
) {
|
||||||
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
|
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
||||||
@ -260,27 +274,30 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
paperConfigField.set(freshWorld, originalServerWorld.paperConfig());
|
paperConfigField.set(freshWorld, originalServerWorld.paperConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
//generator
|
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
|
||||||
// TODO figure out if this is needed. We can probably use
|
if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
|
||||||
// chunkGenerator = newOpts.dimensions().getOrThrow(levelStemResourceKey).generator();
|
|
||||||
// instead.
|
|
||||||
if (originalChunkProvider.getGenerator() instanceof FlatLevelSource flatLevelSource) {
|
|
||||||
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
||||||
chunkGenerator = new FlatLevelSource(originalChunkProvider.getGenerator().structureSets, generatorSettingFlat);
|
chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat);
|
||||||
} else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||||
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier =
|
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField.get(
|
||||||
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
originalGenerator);
|
||||||
.get(originalChunkProvider.getGenerator());
|
BiomeSource biomeSource;
|
||||||
BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource();
|
if (options.hasBiomeType()) {
|
||||||
chunkGenerator = new NoiseBasedChunkGenerator(originalChunkProvider.getGenerator().structureSets,
|
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME
|
||||||
|
.asHolderIdMap()
|
||||||
|
.byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())));
|
||||||
|
} else {
|
||||||
|
biomeSource = originalGenerator.getBiomeSource();
|
||||||
|
}
|
||||||
|
chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets,
|
||||||
noiseBasedChunkGenerator.noises,
|
noiseBasedChunkGenerator.noises,
|
||||||
biomeSource,
|
biomeSource,
|
||||||
generatorSettingBaseSupplier
|
generatorSettingBaseSupplier
|
||||||
);
|
);
|
||||||
} else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator customChunkGenerator) {
|
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
|
||||||
chunkGenerator = customChunkGenerator.delegate;
|
chunkGenerator = customChunkGenerator.delegate;
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName());
|
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (generator != null) {
|
if (generator != null) {
|
||||||
@ -289,6 +306,19 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
chunkGenerator.conf = freshWorld.spigotConfig;
|
chunkGenerator.conf = freshWorld.spigotConfig;
|
||||||
|
|
||||||
|
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
|
||||||
|
// Optimisation for needless ring position calculation when the seed and biome is the same.
|
||||||
|
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(originalGenerator);
|
||||||
|
if (hasGeneratedPositions) {
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions =
|
||||||
|
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(
|
||||||
|
originalGenerator);
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(ringPositions);
|
||||||
|
ringPositionsField.set(chunkGenerator, copy);
|
||||||
|
hasGeneratedPositionsField.setBoolean(chunkGenerator, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
freshChunkProvider = new ServerChunkCache(
|
freshChunkProvider = new ServerChunkCache(
|
||||||
freshWorld,
|
freshWorld,
|
||||||
session,
|
session,
|
||||||
@ -529,6 +559,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
public CompletableFuture<ChunkAccess> lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) {
|
public CompletableFuture<ChunkAccess> lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) {
|
||||||
return CompletableFuture.completedFuture(chunk);
|
return CompletableFuture.completedFuture(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
|||||||
import com.fastasyncworldedit.core.util.MathMan;
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
@ -22,10 +23,14 @@ 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;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
import org.bukkit.generator.WorldInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -521,6 +526,13 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BiomeProvider getBiomeProvider() {
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
return new SingleBiomeProvider();
|
||||||
|
}
|
||||||
|
return originalBukkitWorld.getBiomeProvider();
|
||||||
|
}
|
||||||
|
|
||||||
//classes
|
//classes
|
||||||
|
|
||||||
public enum Concurrency {
|
public enum Concurrency {
|
||||||
@ -624,4 +636,20 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SingleBiomeProvider extends BiomeProvider {
|
||||||
|
|
||||||
|
private final org.bukkit.block.Biome biome = BukkitAdapter.adapt(options.getBiomeType());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.block.Biome getBiome(final WorldInfo worldInfo, final int x, final int y, final int z) {
|
||||||
|
return biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<org.bukkit.block.Biome> getBiomes(final WorldInfo worldInfo) {
|
||||||
|
return Collections.singletonList(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ import org.enginehub.piston.annotation.param.Switch;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
|
import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL;
|
||||||
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION;
|
import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION;
|
||||||
@ -691,6 +692,8 @@ public class RegionCommands {
|
|||||||
Long seed,
|
Long seed,
|
||||||
@Switch(name = 'b', desc = "Regenerate biomes as well")
|
@Switch(name = 'b', desc = "Regenerate biomes as well")
|
||||||
boolean regenBiomes,
|
boolean regenBiomes,
|
||||||
|
@Switch(name = 'r', desc = "If the seed should be randomized")
|
||||||
|
boolean randomSeed,
|
||||||
@Arg(desc = "Biome to apply for this regeneration (only works in overworld)", def = "")
|
@Arg(desc = "Biome to apply for this regeneration (only works in overworld)", def = "")
|
||||||
BiomeType biomeType
|
BiomeType biomeType
|
||||||
) throws WorldEditException {
|
) throws WorldEditException {
|
||||||
@ -703,7 +706,7 @@ public class RegionCommands {
|
|||||||
actor.print(Caption.of("fawe.regen.time"));
|
actor.print(Caption.of("fawe.regen.time"));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
RegenOptions options = RegenOptions.builder()
|
RegenOptions options = RegenOptions.builder()
|
||||||
.seed(seed)
|
.seed(!randomSeed ? seed : new Long(ThreadLocalRandom.current().nextLong()))
|
||||||
.regenBiomes(regenBiomes)
|
.regenBiomes(regenBiomes)
|
||||||
.biomeType(biomeType)
|
.biomeType(biomeType)
|
||||||
.build();
|
.build();
|
||||||
|
Loading…
Reference in New Issue
Block a user