Merge pull request #249 from PolyhedralDev/dev/refactors-6.0

Several refactors
This commit is contained in:
dfsek authored and GitHub committed 2021-07-22 20:29:54 -07:00
commit 1613ea843d
102 files changed
+366 -648

No files matched your search

@@ -5,7 +5,7 @@ import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator; import com.dfsek.terra.addons.biome.pipeline.api.BiomeMutator;
import com.dfsek.terra.api.vector.Vector2; import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public class BiomeHolderImpl implements BiomeHolder { public class BiomeHolderImpl implements BiomeHolder {
private final Vector2 origin; private final Vector2 origin;
@@ -3,7 +3,7 @@ package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder; import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
import com.dfsek.terra.addons.biome.pipeline.api.Stage; import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.vector.Vector2; import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -30,7 +30,7 @@ import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.injection.annotations.Inject; import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
@Addon("biome-provider-pipeline") @Addon("biome-provider-pipeline")
@Author("Terra") @Author("Terra")
@@ -59,7 +59,8 @@ public class BiomePipelineAddon extends TerraAddon {
.applyLoader(SmoothMutator.class, SmoothMutatorTemplate::new) .applyLoader(SmoothMutator.class, SmoothMutatorTemplate::new)
.applyLoader(ExpanderStage.class, ExpanderStageTemplate::new) .applyLoader(ExpanderStage.class, ExpanderStageTemplate::new)
.applyLoader(BiomePipelineProvider.class, () -> new BiomePipelineTemplate(main)) .applyLoader(BiomePipelineProvider.class, () -> new BiomePipelineTemplate(main))
.applyLoader(BIOME_PROVIDER_BUILDER_TOKEN.getType(), new BiomeProviderLoader())) .applyLoader(BIOME_PROVIDER_BUILDER_TOKEN.getType(), new BiomeProviderLoader())
.applyLoader(BiomeSource.Type.class, (t, object, cf) -> BiomeSource.Type.valueOf((String) object)))
.failThrough(); .failThrough();
} }
} }
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.api; package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public interface BiomeHolder { public interface BiomeHolder {
BiomeHolder expand(BiomeExpander expander, long seed); BiomeHolder expand(BiomeExpander expander, long seed);
@@ -8,7 +8,7 @@ import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import java.util.List; import java.util.List;
@@ -6,7 +6,7 @@ import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public class NoiseSourceTemplate extends SourceTemplate { public class NoiseSourceTemplate extends SourceTemplate {
@Value("noise") @Value("noise")
@@ -4,7 +4,7 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource; import com.dfsek.terra.addons.biome.pipeline.source.NoiseSource;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
import java.lang.reflect.AnnotatedType; import java.lang.reflect.AnnotatedType;
import java.util.Map; import java.util.Map;
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.config; package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.loading.object.ObjectTemplate; import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
public abstract class SourceTemplate implements ObjectTemplate<BiomeSource>{ public abstract class SourceTemplate implements ObjectTemplate<BiomeSource>{
@@ -1,4 +1,4 @@
package com.dfsek.terra.api.world.biome.generation.pipeline; package com.dfsek.terra.addons.biome.pipeline.source;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
@@ -3,7 +3,6 @@ package com.dfsek.terra.addons.biome.pipeline.source;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
public class NoiseSource implements BiomeSource { public class NoiseSource implements BiomeSource {
private final ProbabilityCollection<TerraBiome> biomes; private final ProbabilityCollection<TerraBiome> biomes;
@@ -3,12 +3,12 @@ package com.dfsek.terra.addons.chunkgenerator;
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo; import com.dfsek.terra.addons.chunkgenerator.palette.PaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder; import com.dfsek.terra.addons.chunkgenerator.palette.SlantHolder;
import com.dfsek.terra.api.util.MathUtil; import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.generator.Palette; import com.dfsek.terra.api.world.generator.Palette;
import com.dfsek.terra.api.world.generator.Sampler; import com.dfsek.terra.api.world.generator.Sampler;
public final class PaletteUtil { public final class PaletteUtil {
public static Palette getPalette(int x, int y, int z, Generator c, Sampler sampler, PaletteInfo paletteInfo) { public static Palette getPalette(int x, int y, int z, GenerationSettings c, Sampler sampler, PaletteInfo paletteInfo) {
SlantHolder slant = paletteInfo.getSlantHolder(); SlantHolder slant = paletteInfo.getSlantHolder();
if(slant != null) { if(slant != null) {
double slope = MathUtil.derivative(sampler, x, y, z); double slope = MathUtil.derivative(sampler, x, y, z);
@@ -11,16 +11,15 @@ import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.BiomeGrid; import com.dfsek.terra.api.world.BiomeGrid;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkData; import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.api.world.generator.Palette; import com.dfsek.terra.api.world.generator.Palette;
import com.dfsek.terra.api.world.generator.Sampler; import com.dfsek.terra.api.world.generator.Sampler;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
import net.jafama.FastMath; import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -28,10 +27,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class NoiseChunkGenerator3D implements TerraChunkGenerator { public class NoiseChunkGenerator3D implements ChunkGenerator {
private final ConfigPack configPack; private final ConfigPack configPack;
private final TerraPlugin main; private final TerraPlugin main;
private final List<TerraGenerationStage> generationStages = new ArrayList<>(); private final List<GenerationStage> generationStages = new ArrayList<>();
private final BlockState air; private final BlockState air;
@@ -48,14 +47,14 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
int xOrig = (chunkX << 4); int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4); int zOrig = (chunkZ << 4);
long seed = world.getSeed(); long seed = world.getSeed();
BiomeProvider grid = main.getWorld(world).getBiomeProvider(); BiomeProvider grid = world.getBiomeProvider();
for(int x = 0; x < 4; x++) { for(int x = 0; x < 4; x++) {
for(int z = 0; z < 4; z++) { for(int z = 0; z < 4; z++) {
int cx = xOrig + (x << 2); int cx = xOrig + (x << 2);
int cz = zOrig + (z << 2); int cz = zOrig + (z << 2);
TerraBiome b = grid.getBiome(cx, cz, seed); TerraBiome b = grid.getBiome(cx, cz, seed);
biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator(world).getBiomeNoise(), cx, 0, cz, world.getSeed())); biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator().getBiomeNoise(), cx, 0, cz, world.getSeed()));
} }
} }
} }
@@ -75,13 +74,12 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
@SuppressWarnings({"try"}) @SuppressWarnings({"try"})
public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) { public ChunkData generateChunkData(@NotNull World world, Random random, int chunkX, int chunkZ, ChunkData chunk) {
try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) { try(ProfileFrame ignore = main.getProfiler().profile("chunk_base_3d")) {
TerraWorld tw = main.getWorld(world); BiomeProvider grid = world.getBiomeProvider();
BiomeProvider grid = tw.getBiomeProvider();
int xOrig = (chunkX << 4); int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4); int zOrig = (chunkZ << 4);
Sampler sampler = tw.getConfig().getSamplerCache().getChunk(chunkX, chunkZ); Sampler sampler = world.getConfig().getSamplerCache().getChunk(chunkX, chunkZ);
long seed = world.getSeed(); long seed = world.getSeed();
@@ -100,7 +98,7 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
main.logger().info("null palette: " + biome.getID()); main.logger().info("null palette: " + biome.getID());
} }
Generator generator = biome.getGenerator(world); GenerationSettings generationSettings = biome.getGenerator();
int sea = paletteInfo.getSeaLevel(); int sea = paletteInfo.getSeaLevel();
Palette seaPalette = paletteInfo.getOcean(); Palette seaPalette = paletteInfo.getOcean();
@@ -111,7 +109,7 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
if(sampler.sample(x, y, z) > 0) { if(sampler.sample(x, y, z) > 0) {
justSet = true; justSet = true;
data = PaletteUtil.getPalette(x, y, z, generator, sampler, paletteInfo).get(paletteLevel, cx, y, cz, seed); data = PaletteUtil.getPalette(x, y, z, generationSettings, sampler, paletteInfo).get(paletteLevel, cx, y, cz, seed);
chunk.setBlock(x, y, z, data); chunk.setBlock(x, y, z, data);
paletteLevel++; paletteLevel++;
@@ -162,19 +160,18 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
} }
@Override @Override
public List<TerraGenerationStage> getGenerationStages() { public List<GenerationStage> getGenerationStages() {
return generationStages; return generationStages;
} }
@Override @Override
public BlockState getBlock(World world, int x, int y, int z) { public BlockState getBlock(World world, int x, int y, int z) {
TerraWorld terraWorld = main.getWorld(world); BiomeProvider provider = world.getBiomeProvider();
BiomeProvider provider = terraWorld.getBiomeProvider();
TerraBiome biome = provider.getBiome(x, z, world.getSeed()); TerraBiome biome = provider.getBiome(x, z, world.getSeed());
Sampler sampler = terraWorld.getConfig().getSamplerCache().get(x, z); Sampler sampler = world.getConfig().getSamplerCache().get(x, z);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
Palette palette = PaletteUtil.getPalette(x, y, z, biome.getGenerator(world), sampler, paletteInfo); Palette palette = PaletteUtil.getPalette(x, y, z, biome.getGenerator(), sampler, paletteInfo);
int fdX = FastMath.floorMod(x, 16); int fdX = FastMath.floorMod(x, 16);
int fdZ = FastMath.floorMod(z, 16); int fdZ = FastMath.floorMod(z, 16);
double noise = sampler.sample(fdX, y, fdZ); double noise = sampler.sample(fdX, y, fdZ);
@@ -3,7 +3,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.api.util.mutable.MutableInteger; import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkInterpolator; import com.dfsek.terra.api.world.generator.ChunkInterpolator;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -18,7 +18,7 @@ import java.util.function.BiFunction;
*/ */
public class ChunkInterpolator2D implements ChunkInterpolator { public class ChunkInterpolator2D implements ChunkInterpolator {
private final Interpolator[][] interpGrid = new Interpolator[4][4]; private final Interpolator[][] interpGrid = new Interpolator[4][4];
private final BiFunction<Generator, Vector3, Double> noiseGetter; private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
/** /**
* Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates. * Instantiates a 3D ChunkInterpolator3D at a pair of chunk coordinates.
@@ -27,7 +27,7 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
* @param chunkZ Z coordinate of the chunk. * @param chunkZ Z coordinate of the chunk.
* @param provider Biome Provider to use for biome fetching. * @param provider Biome Provider to use for biome fetching.
*/ */
public ChunkInterpolator2D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<Generator, Vector3, Double> noiseGetter) { public ChunkInterpolator2D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
this.noiseGetter = noiseGetter; this.noiseGetter = noiseGetter;
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
@@ -38,15 +38,15 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
for(int x = 0; x < 5; x++) { for(int x = 0; x < 5; x++) {
for(int z = 0; z < 5; z++) { for(int z = 0; z < 5; z++) {
Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator(w); GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
Map<Generator, MutableInteger> genMap = new HashMap<>(); Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
int step = generator.getBlendStep(); int step = generationSettings.getBlendStep();
int blend = generator.getBlendDistance(); int blend = generationSettings.getBlendDistance();
for(int xi = -blend; xi <= blend; xi++) { for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) { for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1 genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(), g -> new MutableInteger(0)).increment(); // Increment by 1
} }
} }
@@ -69,8 +69,8 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
return FastMath.max(FastMath.min(value, high), 0); return FastMath.max(FastMath.min(value, high), 0);
} }
public double computeNoise(Generator generator, double x, double y, double z) { public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
return noiseGetter.apply(generator, new Vector3(x, y, z)); return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
} }
/** /**
@@ -3,7 +3,7 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.api.util.mutable.MutableInteger; import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkInterpolator; import com.dfsek.terra.api.world.generator.ChunkInterpolator;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -18,7 +18,7 @@ import java.util.function.BiFunction;
*/ */
public class ChunkInterpolator3D implements ChunkInterpolator { public class ChunkInterpolator3D implements ChunkInterpolator {
private final Interpolator3[][][] interpGrid; private final Interpolator3[][][] interpGrid;
private final BiFunction<Generator, Vector3, Double> noiseGetter; private final BiFunction<GenerationSettings, Vector3, Double> noiseGetter;
private final int min; private final int min;
private final int max; private final int max;
@@ -30,7 +30,7 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
* @param chunkZ Z coordinate of the chunk. * @param chunkZ Z coordinate of the chunk.
* @param provider Biome Provider to use for biome fetching. * @param provider Biome Provider to use for biome fetching.
*/ */
public ChunkInterpolator3D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<Generator, Vector3, Double> noiseGetter) { public ChunkInterpolator3D(World w, int chunkX, int chunkZ, BiomeProvider provider, BiFunction<GenerationSettings, Vector3, Double> noiseGetter) {
this.noiseGetter = noiseGetter; this.noiseGetter = noiseGetter;
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
@@ -49,15 +49,15 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
for(int x = 0; x < 5; x++) { for(int x = 0; x < 5; x++) {
for(int z = 0; z < 5; z++) { for(int z = 0; z < 5; z++) {
Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator(w); GenerationSettings generationSettings = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator();
Map<Generator, MutableInteger> genMap = new HashMap<>(); Map<GenerationSettings, MutableInteger> genMap = new HashMap<>();
int step = generator.getBlendStep(); int step = generationSettings.getBlendStep();
int blend = generator.getBlendDistance(); int blend = generationSettings.getBlendDistance();
for(int xi = -blend; xi <= blend; xi++) { for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) { for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1 genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(), g -> new MutableInteger(0)).increment(); // Increment by 1
} }
} }
@@ -88,8 +88,8 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
return FastMath.max(FastMath.min(value, high), 0); return FastMath.max(FastMath.min(value, high), 0);
} }
public double computeNoise(Generator generator, double x, double y, double z) { public double computeNoise(GenerationSettings generationSettings, double x, double y, double z) {
return noiseGetter.apply(generator, new Vector3(x, y, z)); return noiseGetter.apply(generationSettings, new Vector3(x, y, z));
} }
/** /**
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ElevationInterpolator { public class ElevationInterpolator {
@@ -13,12 +13,12 @@ public class ElevationInterpolator {
long seed = world.getSeed(); long seed = world.getSeed();
Generator[][] gens = new Generator[18 + 2 * smooth][18 + 2 * smooth]; GenerationSettings[][] gens = new GenerationSettings[18 + 2 * smooth][18 + 2 * smooth];
// Precompute generators. // Precompute generators.
for(int x = -1 - smooth; x <= 16 + smooth; x++) { for(int x = -1 - smooth; x <= 16 + smooth; x++) {
for(int z = -1 - smooth; z <= 16 + smooth; z++) { for(int z = -1 - smooth; z <= 16 + smooth; z++) {
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getGenerator(world); gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getGenerator();
} }
} }
@@ -28,7 +28,7 @@ public class ElevationInterpolator {
double div = 0; double div = 0;
for(int xi = -smooth; xi <= smooth; xi++) { for(int xi = -smooth; xi <= smooth; xi++) {
for(int zi = -smooth; zi <= smooth; zi++) { for(int zi = -smooth; zi <= smooth; zi++) {
Generator gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi]; GenerationSettings gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi];
noise += gen.getElevationSampler().getNoiseSeeded(seed, xOrigin + x, zOrigin + z) * gen.getElevationWeight(); noise += gen.getElevationSampler().getNoiseSeeded(seed, xOrigin + x, zOrigin + z) * gen.getElevationWeight();
div += gen.getElevationWeight(); div += gen.getElevationWeight();
} }
@@ -32,7 +32,7 @@ public class BiomeConfigType implements ConfigType<BiomeTemplate, TerraBiome> {
} }
@Override @Override
public TypeKey<TerraBiome> getTypeClass() { public TypeKey<TerraBiome> getTypeKey() {
return BIOME_TYPE_TOKEN; return BIOME_TYPE_TOKEN;
} }
@@ -14,7 +14,7 @@ public class BiomeFactory implements ConfigFactory<BiomeTemplate, TerraBiome> {
@Override @Override
public TerraBiome build(BiomeTemplate template, TerraPlugin main) { public TerraBiome build(BiomeTemplate template, TerraPlugin main) {
UserDefinedGenerator generator = new UserDefinedGenerator(template.getNoiseEquation(), template.getElevationEquation(), template.getCarvingEquation(), template.getBiomeNoise(), template.getElevationWeight(), UserDefinedGenerationSettings generator = new UserDefinedGenerationSettings(template.getNoiseEquation(), template.getElevationEquation(), template.getCarvingEquation(), template.getBiomeNoise(), template.getElevationWeight(),
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight()); template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generator, template); return new UserDefinedBiome(template.getVanilla(), generator, template);
} }
@@ -2,9 +2,8 @@ package com.dfsek.terra.addons.biome;
import com.dfsek.terra.api.properties.Context; import com.dfsek.terra.api.properties.Context;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import java.util.Set; import java.util.Set;
@@ -13,7 +12,7 @@ import java.util.Set;
* Class representing a config-defined biome * Class representing a config-defined biome
*/ */
public class UserDefinedBiome implements TerraBiome { public class UserDefinedBiome implements TerraBiome {
private final UserDefinedGenerator gen; private final UserDefinedGenerationSettings gen;
private final ProbabilityCollection<Biome> vanilla; private final ProbabilityCollection<Biome> vanilla;
private final String id; private final String id;
private final BiomeTemplate config; private final BiomeTemplate config;
@@ -22,7 +21,7 @@ public class UserDefinedBiome implements TerraBiome {
private final Context context = new Context(); private final Context context = new Context();
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerator gen, BiomeTemplate config) { public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, UserDefinedGenerationSettings gen, BiomeTemplate config) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.gen = gen; this.gen = gen;
this.id = config.getID(); this.id = config.getID();
@@ -52,7 +51,7 @@ public class UserDefinedBiome implements TerraBiome {
} }
@Override @Override
public Generator getGenerator(World w) { public GenerationSettings getGenerator() {
return gen; return gen;
} }
@@ -1,11 +1,9 @@
package com.dfsek.terra.addons.biome; package com.dfsek.terra.addons.biome;
import com.dfsek.terra.addons.biome.holder.PaletteHolder;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import com.dfsek.terra.api.world.biome.PaletteSettings;
public class UserDefinedGenerator implements Generator { public class UserDefinedGenerationSettings implements GenerationSettings {
private final NoiseSampler noise; private final NoiseSampler noise;
private final NoiseSampler elevation; private final NoiseSampler elevation;
@@ -17,7 +15,7 @@ public class UserDefinedGenerator implements Generator {
private final int blendStep; private final int blendStep;
private final double blendWeight; private final double blendWeight;
public UserDefinedGenerator(NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) { public UserDefinedGenerationSettings(NoiseSampler noise, NoiseSampler elevation, NoiseSampler carving, NoiseSampler biomeNoise, double elevationWeight, int blendDistance, int blendStep, double blendWeight) {
this.noise = noise; this.noise = noise;
this.elevation = elevation; this.elevation = elevation;
this.carving = carving; this.carving = carving;
@@ -37,7 +37,7 @@ public class BiomeCommand implements CommandTemplate {
public void execute(CommandSender sender) { public void execute(CommandSender sender) {
Player player = (Player) sender; Player player = (Player) sender;
BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider(); BiomeProvider provider = player.world().getBiomeProvider();
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position(), player.world().getSeed()); UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position(), player.world().getSeed());
sender.sendMessage("You are standing in " + biome.getID()); sender.sendMessage("You are standing in " + biome.getID());
} }
@@ -62,7 +62,7 @@ public class BiomeLocateCommand implements CommandTemplate {
Player player = (Player) sender; Player player = (Player) sender;
new Thread(new AsyncBiomeFinder(main.getWorld(player.world()).getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> { new Thread(new AsyncBiomeFinder(player.world().getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
if(location != null) { if(location != null) {
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position()))); sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
if(teleport) { if(teleport) {
@@ -14,6 +14,6 @@ public class BiomeArgumentParser implements ArgumentParser<TerraBiome> {
@Override @Override
public TerraBiome parse(CommandSender sender, String arg) { public TerraBiome parse(CommandSender sender, String arg) {
Player player = (Player) sender; Player player = (Player) sender;
return main.getWorld(player.world()).getConfig().getRegistry(TerraBiome.class).get(arg); return player.world().getConfig().getRegistry(TerraBiome.class).get(arg);
} }
} }
@@ -17,6 +17,6 @@ public class BiomeTabCompleter implements TabCompleter {
@Override @Override
public List<String> complete(CommandSender sender) { public List<String> complete(CommandSender sender) {
Player player = (Player) sender; Player player = (Player) sender;
return main.getWorld(player.world()).getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(Collectors.toList()); return player.world().getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
} }
} }
@@ -26,12 +26,12 @@ public class CarverCache {
public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) { public CarverCache(World w, TerraPlugin main, UserDefinedCarver carver) {
this.carver = carver; this.carver = carver;
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize()) cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getCarverCacheSize())
.build(new CacheLoader<Long, List<Worm.WormPoint>>() { .build(new CacheLoader<>() {
@Override @Override
public List<Worm.WormPoint> load(@NotNull Long key) { public List<Worm.WormPoint> load(@NotNull Long key) {
int chunkX = (int) (key >> 32); int chunkX = (int) (key >> 32);
int chunkZ = (int) key.longValue(); int chunkZ = (int) key.longValue();
BiomeProvider provider = main.getWorld(w).getBiomeProvider(); BiomeProvider provider = w.getBiomeProvider();
if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new Random(PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) { if(CarverCache.this.carver.isChunkCarved(w, chunkX, chunkZ, new Random(PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed() + CarverCache.this.carver.hashCode())))) {
long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed()); long seed = PopulationUtil.getCarverChunkSeed(chunkX, chunkZ, w.getSeed());
Random r = new Random(seed); Random r = new Random(seed);
@@ -4,22 +4,20 @@ import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.BlockType; import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig; import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.handle.WorldHandle;
import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.PopulationUtil;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.Chunkified; import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
public class CavePopulator implements TerraGenerationStage, Chunkified { public class CavePopulator implements GenerationStage, Chunkified {
private static final Map<BlockType, BlockState> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time. private static final Map<BlockType, BlockState> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
private final TerraPlugin main; private final TerraPlugin main;
@@ -30,11 +28,9 @@ public class CavePopulator implements TerraGenerationStage, Chunkified {
@SuppressWarnings("try") @SuppressWarnings("try")
@Override @Override
public void populate(@NotNull World world, @NotNull Chunk chunk) { public void populate(@NotNull World world, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
WorldHandle handle = main.getWorldHandle();
try(ProfileFrame ignore = main.getProfiler().profile("carving")) { try(ProfileFrame ignore = main.getProfiler().profile("carving")) {
Random random = PopulationUtil.getRandom(chunk); Random random = PopulationUtil.getRandom(chunk);
WorldConfig config = tw.getConfig(); WorldConfig config = world.getConfig();
if(config.disableCarving()) return; if(config.disableCarving()) return;
for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) { for(UserDefinedCarver c : config.getRegistry(UserDefinedCarver.class).entries()) {
@@ -26,7 +26,7 @@ public class FeatureConfigType implements ConfigType<FeatureTemplate, Feature> {
} }
@Override @Override
public TypeKey<Feature> getTypeClass() { public TypeKey<Feature> getTypeKey() {
return FEATURE_TYPE_KEY; return FEATURE_TYPE_KEY;
} }
@@ -26,7 +26,7 @@ public class FloraConfigType implements ConfigType<FloraTemplate, Flora> {
} }
@Override @Override
public TypeKey<Flora> getTypeClass() { public TypeKey<Flora> getTypeKey() {
return FLORA_TYPE_TOKEN; return FLORA_TYPE_TOKEN;
} }
@@ -25,7 +25,7 @@ public class OreConfigType implements ConfigType<OreTemplate, Ore> {
} }
@Override @Override
public TypeKey<Ore> getTypeClass() { public TypeKey<Ore> getTypeKey() {
return ORE_TYPE_TOKEN; return ORE_TYPE_TOKEN;
} }
@@ -4,15 +4,14 @@ import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.profiler.ProfileFrame; import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.PopulationUtil;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Random; import java.util.Random;
public class OrePopulator implements TerraGenerationStage { public class OrePopulator implements GenerationStage {
private final TerraPlugin main; private final TerraPlugin main;
public OrePopulator(TerraPlugin main) { public OrePopulator(TerraPlugin main) {
@@ -22,16 +21,15 @@ public class OrePopulator implements TerraGenerationStage {
@SuppressWarnings("try") @SuppressWarnings("try")
@Override @Override
public void populate(@NotNull World world, @NotNull Chunk chunk) { public void populate(@NotNull World world, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFrame ignore = main.getProfiler().profile("ore")) { try(ProfileFrame ignore = main.getProfiler().profile("ore")) {
if(tw.getConfig().disableOres()) return; if(world.getConfig().disableOres()) return;
for(int cx = -1; cx <= 1; cx++) { for(int cx = -1; cx <= 1; cx++) {
for(int cz = -1; cz <= 1; cz++) { for(int cz = -1; cz <= 1; cz++) {
Random random = new Random(PopulationUtil.getCarverChunkSeed(chunk.getX() + cx, chunk.getZ() + cz, world.getSeed())); Random random = new Random(PopulationUtil.getCarverChunkSeed(chunk.getX() + cx, chunk.getZ() + cz, world.getSeed()));
int originX = ((chunk.getX() + cx) << 4); int originX = ((chunk.getX() + cx) << 4);
int originZ = ((chunk.getZ() + cz) << 4); int originZ = ((chunk.getZ() + cz) << 4);
TerraBiome b = tw.getBiomeProvider().getBiome(originX + 8, originZ + 8, world.getSeed()); TerraBiome b = world.getBiomeProvider().getBiome(originX + 8, originZ + 8, world.getSeed());
/* /*
BiomeTemplate config = ((UserDefinedBiome) b).getConfig(); BiomeTemplate config = ((UserDefinedBiome) b).getConfig();
int finalCx = cx; int finalCx = cx;
@@ -34,7 +34,7 @@ public class PaletteConfigType implements ConfigType<PaletteTemplate, Palette> {
} }
@Override @Override
public TypeKey<Palette> getTypeClass() { public TypeKey<Palette> getTypeKey() {
return PALETTE_TYPE_TOKEN; return PALETTE_TYPE_TOKEN;
} }
@@ -8,17 +8,16 @@ import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.PopulationUtil;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.Chunkified; import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
import net.jafama.FastMath; import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Random; import java.util.Random;
public class StructurePopulator implements TerraGenerationStage, Chunkified { public class StructurePopulator implements GenerationStage, Chunkified {
private final TerraPlugin main; private final TerraPlugin main;
public StructurePopulator(TerraPlugin main) { public StructurePopulator(TerraPlugin main) {
@@ -28,14 +27,13 @@ public class StructurePopulator implements TerraGenerationStage, Chunkified {
@SuppressWarnings("try") @SuppressWarnings("try")
@Override @Override
public void populate(@NotNull World world, @NotNull Chunk chunk) { public void populate(@NotNull World world, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFrame ignore = main.getProfiler().profile("structure")) { try(ProfileFrame ignore = main.getProfiler().profile("structure")) {
if(tw.getConfig().disableStructures()) return; if(world.getConfig().disableStructures()) return;
int cx = (chunk.getX() << 4); int cx = (chunk.getX() << 4);
int cz = (chunk.getZ() << 4); int cz = (chunk.getZ() << 4);
BiomeProvider provider = tw.getBiomeProvider(); BiomeProvider provider = world.getBiomeProvider();
WorldConfig config = tw.getConfig(); WorldConfig config = world.getConfig();
for(ConfiguredStructure conf : config.getRegistry(TerraStructure.class).entries()) { for(ConfiguredStructure conf : config.getRegistry(TerraStructure.class).entries()) {
Vector3 spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()); Vector3 spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed());
@@ -61,7 +61,7 @@ public class StructureLocateCommand implements CommandTemplate {
public void execute(CommandSender sender) { public void execute(CommandSender sender) {
Player player = (Player) sender; Player player = (Player) sender;
new Thread(new AsyncStructureFinder(main.getWorld(player.world()).getBiomeProvider(), structure, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> { new Thread(new AsyncStructureFinder(player.world().getBiomeProvider(), structure, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
if(location != null) { if(location != null) {
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", structure.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position()))); sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", structure.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
if(teleport) { if(teleport) {
@@ -13,6 +13,6 @@ public class ScriptArgumentParser implements ArgumentParser<Structure> {
@Override @Override
public Structure parse(CommandSender sender, String arg) { public Structure parse(CommandSender sender, String arg) {
return main.getWorld(((Player) sender).world()).getConfig().getRegistry(Structure.class).get(arg); return ((Player) sender).world().getConfig().getRegistry(Structure.class).get(arg);
} }
} }
@@ -13,6 +13,6 @@ public class StructureArgumentParser implements ArgumentParser<ConfiguredStructu
@Override @Override
public ConfiguredStructure parse(CommandSender sender, String arg) { public ConfiguredStructure parse(CommandSender sender, String arg) {
return main.getWorld(((Player) sender).world()).getConfig().getRegistry(ConfiguredStructure.class).get(arg); return ((Player) sender).world().getConfig().getRegistry(ConfiguredStructure.class).get(arg);
} }
} }
@@ -16,6 +16,6 @@ public class ScriptCompleter implements TabCompleter {
@Override @Override
public List<String> complete(CommandSender sender) { public List<String> complete(CommandSender sender) {
return main.getWorld(((Player) sender).world()).getConfig().getRegistry(Structure.class).entries().stream().map(Structure::getId).collect(Collectors.toList()); return ((Player) sender).world().getConfig().getRegistry(Structure.class).entries().stream().map(Structure::getID).collect(Collectors.toList());
} }
} }
@@ -17,6 +17,6 @@ public class StructureCompleter implements TabCompleter {
@Override @Override
public List<String> complete(CommandSender sender) { public List<String> complete(CommandSender sender) {
Player player = (Player) sender; Player player = (Player) sender;
return new ArrayList<>(main.getWorld(player.world()).getConfig().getRegistry(ConfiguredStructure.class).keys()); return new ArrayList<>(player.world().getConfig().getRegistry(ConfiguredStructure.class).keys());
} }
} }
@@ -7,11 +7,10 @@ import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.PopulationUtil;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
public class FeatureGenerationStage implements TerraGenerationStage { public class FeatureGenerationStage implements GenerationStage {
private final TerraPlugin main; private final TerraPlugin main;
public FeatureGenerationStage(TerraPlugin main) { public FeatureGenerationStage(TerraPlugin main) {
@@ -21,7 +20,6 @@ public class FeatureGenerationStage implements TerraGenerationStage {
@Override @Override
@SuppressWarnings("try") @SuppressWarnings("try")
public void populate(World world, Chunk chunk) { public void populate(World world, Chunk chunk) {
TerraWorld terraWorld = main.getWorld(world);
try(ProfileFrame ignore = main.getProfiler().profile("feature")) { try(ProfileFrame ignore = main.getProfiler().profile("feature")) {
int cx = chunk.getX() << 4; int cx = chunk.getX() << 4;
int cz = chunk.getZ() << 4; int cz = chunk.getZ() << 4;
@@ -31,13 +29,13 @@ public class FeatureGenerationStage implements TerraGenerationStage {
int tx = cx + x; int tx = cx + x;
int tz = cz + z; int tz = cz + z;
ColumnImpl column = new ColumnImpl(tx, tz, world); ColumnImpl column = new ColumnImpl(tx, tz, world);
terraWorld.getBiomeProvider().getBiome(tx, tz, seed).getContext().get(BiomeFeatures.class).getFeatures().forEach(feature -> { world.getBiomeProvider().getBiome(tx, tz, seed).getContext().get(BiomeFeatures.class).getFeatures().forEach(feature -> {
if(feature.getDistributor().matches(tx, tz, seed)) { if(feature.getDistributor().matches(tx, tz, seed)) {
feature.getLocator() feature.getLocator()
.getSuitableCoordinates(column) .getSuitableCoordinates(column)
.forEach(y -> .forEach(y ->
feature.getStructure(world, tx, y, tz) feature.getStructure(world, tx, y, tz)
.generateDirect(new Vector3(tx, y, tz), world, PopulationUtil.getRandom(chunk), Rotation.NONE) .generate(new Vector3(tx, y, tz), world, PopulationUtil.getRandom(chunk), Rotation.NONE)
); );
} }
}); });
@@ -5,10 +5,9 @@ import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.PopulationUtil;
import com.dfsek.terra.api.vector.Vector2; import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.TerraGenerationStage; import com.dfsek.terra.api.world.generator.GenerationStage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
@@ -19,7 +18,7 @@ import java.util.Random;
/** /**
* Populates Flora * Populates Flora
*/ */
public class FloraGenerationStage implements TerraGenerationStage { public class FloraGenerationStage implements GenerationStage {
private final TerraPlugin main; private final TerraPlugin main;
public FloraGenerationStage(TerraPlugin main) { public FloraGenerationStage(TerraPlugin main) {
@@ -29,12 +28,11 @@ public class FloraGenerationStage implements TerraGenerationStage {
@SuppressWarnings("try") @SuppressWarnings("try")
@Override @Override
public void populate(@NotNull World world, @NotNull Chunk chunk) { public void populate(@NotNull World world, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFrame ignore = main.getProfiler().profile("flora")) { try(ProfileFrame ignore = main.getProfiler().profile("flora")) {
if(tw.getConfig().disableFlora()) return; if(world.getConfig().disableFlora()) return;
long seed = world.getSeed(); long seed = world.getSeed();
BiomeProvider provider = tw.getBiomeProvider(); BiomeProvider provider = world.getBiomeProvider();
Map<Vector2, List<FloraLayer>> layers = new HashMap<>(); Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
for(int x = 0; x < 16; x++) { for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) { for(int z = 0; z < 16; z++) {
@@ -37,7 +37,7 @@ public class TerraScriptAddon extends TerraAddon {
for(Map.Entry<String, InputStream> entry : entries) { for(Map.Entry<String, InputStream> entry : entries) {
try { try {
StructureScript structureScript = new StructureScript(entry.getValue(), main, structureRegistry, lootRegistry, event.getPack().getRegistryFactory().create()); StructureScript structureScript = new StructureScript(entry.getValue(), main, structureRegistry, lootRegistry, event.getPack().getRegistryFactory().create());
structureRegistry.register(structureScript.getId(), structureScript); structureRegistry.register(structureScript.getID(), structureScript);
} catch(ParseException e) { } catch(ParseException e) {
throw new LoadException("Failed to load script: ", e); throw new LoadException("Failed to load script: ", e);
} }
@@ -21,6 +21,6 @@ public class BufferedEntity implements BufferedItem {
@Override @Override
public void paste(Vector3 origin, World world) { public void paste(Vector3 origin, World world) {
Entity entity = world.spawnEntity(origin.clone().add(0.5, 0, 0.5), type); Entity entity = world.spawnEntity(origin.clone().add(0.5, 0, 0.5), type);
main.getEventManager().callEvent(new EntitySpawnEvent(entity.world().getTerraGenerator().getConfigPack(), entity)); main.getEventManager().callEvent(new EntitySpawnEvent(entity.world().getConfig().getPack(), entity));
} }
} }
@@ -33,7 +33,7 @@ public class BufferedLootApplication implements BufferedItem {
} }
Container container = (Container) data; Container container = (Container) data;
LootPopulateEvent event = new LootPopulateEvent(container, table, world.getTerraGenerator().getConfigPack(), structure); LootPopulateEvent event = new LootPopulateEvent(container, table, world.getConfig().getPack(), structure);
main.getEventManager().callEvent(event); main.getEventManager().callEvent(event);
if(event.isCancelled()) return; if(event.isCancelled()) return;
@@ -112,17 +112,6 @@ public class StructureScript implements Structure {
this.cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getStructureCache()).build(); this.cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getStructureCache()).build();
} }
@Override
@SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript:" + id)) {
StructureBuffer buffer = new StructureBuffer(location);
boolean level = applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0));
buffer.paste(location, world);
return level;
}
}
@Override @Override
@SuppressWarnings("try") @SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) { public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) {
@@ -133,7 +122,6 @@ public class StructureScript implements Structure {
} }
} }
@Override
@SuppressWarnings("try") @SuppressWarnings("try")
public boolean test(Vector3 location, World world, Random random, Rotation rotation) { public boolean test(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_test:" + id)) { try(ProfileFrame ignore = main.getProfiler().profile("terrascript_test:" + id)) {
@@ -164,7 +152,7 @@ public class StructureScript implements Structure {
@Override @Override
@SuppressWarnings("try") @SuppressWarnings("try")
public boolean generateDirect(Vector3 location, World world, Random random, Rotation rotation) { public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_direct:" + id)) { try(ProfileFrame ignore = main.getProfiler().profile("terrascript_direct:" + id)) {
DirectBuffer buffer = new DirectBuffer(location, world); DirectBuffer buffer = new DirectBuffer(location, world);
return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0)); return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0));
@@ -172,7 +160,7 @@ public class StructureScript implements Structure {
} }
@Override @Override
public String getId() { public String getID() {
return id; return id;
} }
@@ -38,7 +38,7 @@ public class BiomeFunction implements Function<String> {
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
BiomeProvider grid = main.getWorld(arguments.getWorld()).getBiomeProvider(); BiomeProvider grid = arguments.getWorld().getBiomeProvider();
return grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))), arguments.getWorld().getSeed()).getID(); return grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))), arguments.getWorld().getSeed()).getID();
} }
@@ -10,7 +10,6 @@ import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.util.RotationUtil; import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2; import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.SamplerCache; import com.dfsek.terra.api.world.generator.SamplerCache;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -50,8 +49,7 @@ public class CheckFunction implements Function<String> {
private String apply(Vector3 vector, World world) { private String apply(Vector3 vector, World world) {
int y = vector.getBlockY(); int y = vector.getBlockY();
if(y >= world.getMaxHeight() || y < 0) return "AIR"; if(y >= world.getMaxHeight() || y < 0) return "AIR";
TerraWorld tw = main.getWorld(world); SamplerCache cache = world.getConfig().getSamplerCache();
SamplerCache cache = tw.getConfig().getSamplerCache();
double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), cache); double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), cache);
if(comp > 0) return "LAND"; // If noise val is greater than zero, location will always be land. if(comp > 0) return "LAND"; // If noise val is greater than zero, location will always be land.
@@ -0,0 +1,5 @@
package com.dfsek.terra.api;
public interface StringIdentifiable {
String getID();
}
@@ -11,8 +11,6 @@ import com.dfsek.terra.api.profiler.Profiler;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.tectonic.LoaderRegistrar; import com.dfsek.terra.api.tectonic.LoaderRegistrar;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World;
import java.io.File; import java.io.File;
@@ -22,8 +20,6 @@ import java.io.File;
public interface TerraPlugin extends LoaderRegistrar { public interface TerraPlugin extends LoaderRegistrar {
WorldHandle getWorldHandle(); WorldHandle getWorldHandle();
TerraWorld getWorld(World world);
Logger logger(); Logger logger();
PluginConfig getTerraConfig(); PluginConfig getTerraConfig();
@@ -1,7 +1,7 @@
package com.dfsek.terra.api.config; package com.dfsek.terra.api.config;
import com.dfsek.tectonic.config.ConfigTemplate; import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.terra.api.StringIdentifiable;
public interface AbstractableTemplate extends ConfigTemplate { public interface AbstractableTemplate extends ConfigTemplate, StringIdentifiable {
String getID();
} }
@@ -1,5 +1,6 @@
package com.dfsek.terra.api.config; package com.dfsek.terra.api.config;
import com.dfsek.terra.api.StringIdentifiable;
import com.dfsek.terra.api.addon.TerraAddon; import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.meta.RegistryFactory; import com.dfsek.terra.api.registry.meta.RegistryFactory;
@@ -7,7 +8,7 @@ import com.dfsek.terra.api.registry.meta.RegistryHolder;
import com.dfsek.terra.api.tectonic.LoaderHolder; import com.dfsek.terra.api.tectonic.LoaderHolder;
import com.dfsek.terra.api.tectonic.LoaderRegistrar; import com.dfsek.terra.api.tectonic.LoaderRegistrar;
import com.dfsek.terra.api.util.reflection.TypeKey; import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider; import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
import com.dfsek.terra.api.world.generator.GenerationStageProvider; import com.dfsek.terra.api.world.generator.GenerationStageProvider;
@@ -17,7 +18,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public interface ConfigPack extends LoaderRegistrar, LoaderHolder, RegistryHolder { public interface ConfigPack extends LoaderRegistrar, LoaderHolder, RegistryHolder, StringIdentifiable {
BiomeProvider getBiomeProviderBuilder(); BiomeProvider getBiomeProviderBuilder();
<T> CheckedRegistry<T> getOrCreateRegistry(Type clazz); <T> CheckedRegistry<T> getOrCreateRegistry(Type clazz);
@@ -29,7 +30,7 @@ public interface ConfigPack extends LoaderRegistrar, LoaderHolder, RegistryHolde
return getOrCreateRegistry(type.getType()); return getOrCreateRegistry(type.getType());
} }
WorldConfig toWorldConfig(TerraWorld world); WorldConfig toWorldConfig(World world);
List<GenerationStageProvider> getStages(); List<GenerationStageProvider> getStages();
@@ -39,8 +40,6 @@ public interface ConfigPack extends LoaderRegistrar, LoaderHolder, RegistryHolde
Set<TerraAddon> addons(); Set<TerraAddon> addons();
String getID();
String getAuthor(); String getAuthor();
String getVersion(); String getVersion();
@@ -11,7 +11,7 @@ public interface ConfigType<T extends AbstractableTemplate, R> {
ConfigFactory<T, R> getFactory(); ConfigFactory<T, R> getFactory();
TypeKey<R> getTypeClass(); TypeKey<R> getTypeKey();
Supplier<OpenRegistry<R>> registrySupplier(ConfigPack pack); Supplier<OpenRegistry<R>> registrySupplier(ConfigPack pack);
} }
@@ -1,23 +1,24 @@
package com.dfsek.terra.api.config; package com.dfsek.terra.api.config;
import com.dfsek.terra.api.StringIdentifiable;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.SamplerCache; import com.dfsek.terra.api.world.generator.SamplerCache;
import com.dfsek.terra.api.world.generator.TerraGenerationStage;
import java.util.List;
import java.util.Map; import java.util.Map;
public interface WorldConfig { public interface WorldConfig extends StringIdentifiable {
<T> Registry<T> getRegistry(Class<T> clazz); <T> Registry<T> getRegistry(Class<T> clazz);
TerraWorld getWorld(); World getWorld();
SamplerCache getSamplerCache(); SamplerCache getSamplerCache();
BiomeProvider getProvider(); BiomeProvider getProvider();
ConfigPack getPack();
int elevationBlend(); int elevationBlend();
boolean disableTrees(); boolean disableTrees();
@@ -30,8 +31,6 @@ public interface WorldConfig {
boolean disableStructures(); boolean disableStructures();
String getID();
String getAuthor(); String getAuthor();
String getVersion(); String getVersion();
@@ -51,13 +51,13 @@ public class ConfigurationLoadEvent implements PackEvent, FailThroughEvent {
} }
public boolean is(Class<?> clazz) { public boolean is(Class<?> clazz) {
return clazz.isAssignableFrom(type.getTypeClass().getRawType()); return clazz.isAssignableFrom(type.getTypeKey().getRawType());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T getLoadedObject(Class<T> clazz) { public <T> T getLoadedObject(Class<T> clazz) {
if(!clazz.isAssignableFrom(type.getTypeClass().getRawType())) if(!clazz.isAssignableFrom(type.getTypeKey().getRawType()))
throw new ClassCastException("Cannot assign object from loader of type " + ReflectionUtil.typeToString(type.getTypeClass().getType()) + " to class " + clazz.getCanonicalName()); throw new ClassCastException("Cannot assign object from loader of type " + ReflectionUtil.typeToString(type.getTypeKey().getType()) + " to class " + clazz.getCanonicalName());
return (T) loaded; return (T) loaded;
} }
@@ -25,13 +25,13 @@ public abstract class ConfigTypeLoadEvent implements PackEvent, FailThroughEvent
} }
public boolean is(Class<?> clazz) { public boolean is(Class<?> clazz) {
return clazz.isAssignableFrom(type.getTypeClass().getRawType()); return clazz.isAssignableFrom(type.getTypeKey().getRawType());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> CheckedRegistry<T> getRegistry(Class<T> clazz) { public <T> CheckedRegistry<T> getRegistry(Class<T> clazz) {
if(!clazz.isAssignableFrom(type.getTypeClass().getRawType())) if(!clazz.isAssignableFrom(type.getTypeKey().getRawType()))
throw new ClassCastException("Cannot assign object from loader of type " + ReflectionUtil.typeToString(type.getTypeClass().getType()) + " to class " + clazz.getCanonicalName()); throw new ClassCastException("Cannot assign object from loader of type " + ReflectionUtil.typeToString(type.getTypeKey().getType()) + " to class " + clazz.getCanonicalName());
return (CheckedRegistry<T>) registry; return (CheckedRegistry<T>) registry;
} }
} }
@@ -1,32 +0,0 @@
package com.dfsek.terra.api.event.events.world;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.api.world.TerraWorld;
/**
* Called upon initialization of a TerraWorld.
*/
public class TerraWorldLoadEvent implements PackEvent {
private final TerraWorld world;
private final ConfigPack pack;
public TerraWorldLoadEvent(TerraWorld world, ConfigPack pack) {
this.world = world;
this.pack = pack;
}
public TerraWorld getWorld() {
return world;
}
public ConfigPack getPack() {
return pack;
}
public WorldConfig getWorldConfig() {
return world.getConfig();
}
}
@@ -1,5 +1,6 @@
package com.dfsek.terra.api.structure; package com.dfsek.terra.api.structure;
import com.dfsek.terra.api.StringIdentifiable;
import com.dfsek.terra.api.structure.buffer.Buffer; import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.rotation.Rotation; import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
@@ -8,29 +9,10 @@ import com.dfsek.terra.api.world.World;
import java.util.Random; import java.util.Random;
public interface Structure { public interface Structure extends StringIdentifiable {
/**
* Paste the structure at a location
*
* @param location Location to paste structure
* @param world
* @param rotation Rotation of structure
* @return Whether generation was successful
*/
@SuppressWarnings("try")
boolean generate(Vector3 location, World world, Random random, Rotation rotation);
@SuppressWarnings("try")
boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation); boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation);
@SuppressWarnings("try")
boolean test(Vector3 location, World world, Random random, Rotation rotation);
@SuppressWarnings("try")
boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions); boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions);
@SuppressWarnings("try") boolean generate(Vector3 location, World world, Random random, Rotation rotation);
boolean generateDirect(Vector3 location, World world, Random random, Rotation rotation);
String getId();
} }
@@ -1,16 +1,15 @@
package com.dfsek.terra.api.structure.configured; package com.dfsek.terra.api.structure.configured;
import com.dfsek.terra.api.StringIdentifiable;
import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.StructureSpawn; import com.dfsek.terra.api.structure.StructureSpawn;
import com.dfsek.terra.api.util.Range; import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public interface ConfiguredStructure { public interface ConfiguredStructure extends StringIdentifiable {
ProbabilityCollection<Structure> getStructure(); ProbabilityCollection<Structure> getStructure();
Range getSpawnStart(); Range getSpawnStart();
StructureSpawn getSpawn(); StructureSpawn getSpawn();
String getID();
} }
@@ -1,26 +0,0 @@
package com.dfsek.terra.api.world;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public interface TerraWorld {
World getWorld();
BiomeProvider getBiomeProvider();
WorldConfig getConfig();
/**
* Get a block at an ungenerated location
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @return BlockData
*/
BlockState getUngeneratedBlock(int x, int y, int z);
BlockState getUngeneratedBlock(Vector3 v);
}
@@ -3,20 +3,18 @@ package com.dfsek.terra.api.world;
import com.dfsek.terra.api.Handle; import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
public interface World extends Handle { public interface World extends Handle {
long getSeed(); long getSeed();
int getMaxHeight(); int getMaxHeight();
ChunkGenerator getGenerator();
Chunk getChunkAt(int x, int z); Chunk getChunkAt(int x, int z);
default Chunk getChunkAt(Vector3 location) { default Chunk getChunkAt(Vector3 location) {
@@ -53,11 +51,9 @@ public interface World extends Handle {
int getMinHeight(); int getMinHeight();
default boolean isTerraWorld() { ChunkGenerator getGenerator();
return getGenerator().getHandle() instanceof GeneratorWrapper;
}
default TerraChunkGenerator getTerraGenerator() { BiomeProvider getBiomeProvider();
return ((GeneratorWrapper) getGenerator().getHandle()).getHandle();
} WorldConfig getConfig();
} }
@@ -2,7 +2,7 @@ package com.dfsek.terra.api.world.biome;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
public interface Generator { public interface GenerationSettings {
/** /**
* Gets the noise sampler instance to use for base terrain. * Gets the noise sampler instance to use for base terrain.
* *
@@ -3,7 +3,6 @@ package com.dfsek.terra.api.world.biome;
import com.dfsek.terra.api.properties.PropertyHolder; import com.dfsek.terra.api.properties.PropertyHolder;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.World;
import java.util.Set; import java.util.Set;
@@ -24,7 +23,7 @@ public interface TerraBiome extends PropertyHolder {
* *
* @return BiomeTerrain - The terrain generation instance. * @return BiomeTerrain - The terrain generation instance.
*/ */
Generator getGenerator(World w); GenerationSettings getGenerator();
int getColor(); int getColor();
@@ -1,7 +1,33 @@
package com.dfsek.terra.api.world.generator; package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.Handle; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.BiomeGrid;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import org.jetbrains.annotations.NotNull;
public interface ChunkGenerator extends Handle { import java.util.List;
import java.util.Random;
public interface ChunkGenerator {
ChunkData generateChunkData(@NotNull World world, Random random, int x, int z, ChunkData original);
void generateBiomes(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome);
ConfigPack getConfigPack();
TerraPlugin getMain();
Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth);
List<GenerationStage> getGenerationStages();
BlockState getBlock(World world, int x, int y, int z);
default BlockState getBlock(World world, Vector3 vector3) {
return getBlock(world, vector3.getBlockX(), vector3.getBlockY(), vector3.getBlockZ());
}
} }
@@ -3,5 +3,5 @@ package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
public interface ChunkGeneratorProvider { public interface ChunkGeneratorProvider {
TerraChunkGenerator newInstance(ConfigPack pack); ChunkGenerator newInstance(ConfigPack pack);
} }
@@ -1,7 +1,7 @@
package com.dfsek.terra.api.world.generator; package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.util.mutable.MutableInteger; import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.GenerationSettings;
import java.util.Map; import java.util.Map;
@@ -20,11 +20,11 @@ public interface ChunkInterpolator {
} }
default double computeNoise(Map<Generator, MutableInteger> gens, double x, double y, double z) { default double computeNoise(Map<GenerationSettings, MutableInteger> gens, double x, double y, double z) {
double n = 0; double n = 0;
double div = 0; double div = 0;
for(Map.Entry<Generator, MutableInteger> entry : gens.entrySet()) { for(Map.Entry<GenerationSettings, MutableInteger> entry : gens.entrySet()) {
Generator gen = entry.getKey(); GenerationSettings gen = entry.getKey();
int weight = entry.getValue().get(); int weight = entry.getValue().get();
double noise = computeNoise(gen, x, y, z); double noise = computeNoise(gen, x, y, z);
@@ -34,5 +34,5 @@ public interface ChunkInterpolator {
return n / div; return n / div;
} }
double computeNoise(Generator generator, double x, double y, double z); double computeNoise(GenerationSettings generationSettings, double x, double y, double z);
} }
@@ -1,11 +1,8 @@
package com.dfsek.terra.api.world.generator; package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import java.util.Random; public interface GenerationStage {
void populate(World world, Chunk chunk);
public interface GenerationStage extends Handle {
void populate(World world, Random random, Chunk chunk);
} }
@@ -3,5 +3,5 @@ package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
public interface GenerationStageProvider { public interface GenerationStageProvider {
TerraGenerationStage newInstance(ConfigPack pack); GenerationStage newInstance(ConfigPack pack);
} }
@@ -4,5 +4,5 @@ import com.dfsek.terra.api.Handle;
public interface GeneratorWrapper extends Handle { public interface GeneratorWrapper extends Handle {
@Override @Override
TerraChunkGenerator getHandle(); ChunkGenerator getHandle();
} }
@@ -1,33 +0,0 @@
package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.BiomeGrid;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Random;
public interface TerraChunkGenerator {
ChunkData generateChunkData(@NotNull World world, Random random, int x, int z, ChunkData original);
void generateBiomes(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome);
ConfigPack getConfigPack();
TerraPlugin getMain();
Sampler createSampler(int chunkX, int chunkZ, BiomeProvider provider, World world, int elevationSmooth);
List<TerraGenerationStage> getGenerationStages();
BlockState getBlock(World world, int x, int y, int z);
default BlockState getBlock(World world, Vector3 vector3) {
return getBlock(world, vector3.getBlockX(), vector3.getBlockY(), vector3.getBlockZ());
}
}
@@ -1,8 +0,0 @@
package com.dfsek.terra.api.world.generator;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
public interface TerraGenerationStage {
void populate(World world, Chunk chunk);
}
@@ -23,6 +23,6 @@ public class GetBlockCommand implements CommandTemplate {
@Override @Override
public void execute(CommandSender sender) { public void execute(CommandSender sender) {
Player player = (Player) sender; Player player = (Player) sender;
sender.sendMessage("Block: " + main.getWorld(player.world()).getUngeneratedBlock(player.position()).getAsString()); sender.sendMessage("Block: " + player.world().getGenerator().getBlock(player.world(), player.position()).getAsString());
} }
} }
@@ -66,7 +66,7 @@ public class TerraCommandManager implements CommandManager {
return; return;
} }
if(commandClass.isAnnotationPresent(WorldCommand.class) && (!(sender instanceof Player) || !(((Player) sender).world()).isTerraWorld())) { if(commandClass.isAnnotationPresent(WorldCommand.class) && (!(sender instanceof Player))) {
sender.sendMessage("Command must be executed in a Terra world."); sender.sendMessage("Command must be executed in a Terra world.");
return; return;
} }
@@ -9,7 +9,6 @@ import com.dfsek.terra.api.tectonic.LoaderRegistrar;
import com.dfsek.terra.api.util.Range; import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.collection.MaterialSet; import com.dfsek.terra.api.util.collection.MaterialSet;
import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
import com.dfsek.terra.config.loaders.LinkedHashMapLoader; import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
import com.dfsek.terra.config.loaders.MaterialSetLoader; import com.dfsek.terra.config.loaders.MaterialSetLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
@@ -29,8 +28,7 @@ public class GenericLoaders implements LoaderRegistrar {
registry.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader()) registry.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
.registerLoader(Range.class, new RangeLoader()) .registerLoader(Range.class, new RangeLoader())
.registerLoader(MaterialSet.class, new MaterialSetLoader()) .registerLoader(MaterialSet.class, new MaterialSetLoader())
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader()) .registerLoader(LinkedHashMap.class, new LinkedHashMapLoader());
.registerLoader(BiomeSource.Type.class, (t, object, cf) -> BiomeSource.Type.valueOf((String) object));
if(main != null) { if(main != null) {
registry.registerLoader(TerraAddon.class, main.getAddons()) registry.registerLoader(TerraAddon.class, main.getAddons())
@@ -2,13 +2,14 @@ package com.dfsek.terra.config.dummy;
import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.GeneratorWrapper;
public class DummyWorld implements World { public class DummyWorld implements World {
@Override @Override
@@ -26,11 +27,6 @@ public class DummyWorld implements World {
return 255; return 255;
} }
@Override
public ChunkGenerator getGenerator() {
return () -> (GeneratorWrapper) () -> null;
}
@Override @Override
public Chunk getChunkAt(int x, int z) { public Chunk getChunkAt(int x, int z) {
throw new UnsupportedOperationException("Cannot get chunk in DummyWorld"); throw new UnsupportedOperationException("Cannot get chunk in DummyWorld");
@@ -60,4 +56,19 @@ public class DummyWorld implements World {
public int getMinHeight() { public int getMinHeight() {
return 0; return 0;
} }
@Override
public ChunkGenerator getGenerator() {
throw new UnsupportedOperationException("Cannot get generator of DummyWorld");
}
@Override
public BiomeProvider getBiomeProvider() {
throw new UnsupportedOperationException("Cannot get biome provider of DummyWorld");
}
@Override
public WorldConfig getConfig() {
throw new UnsupportedOperationException("Cannot get config of DummyWorld");
}
} }
@@ -32,7 +32,7 @@ import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import com.dfsek.terra.api.registry.meta.RegistryFactory; import com.dfsek.terra.api.registry.meta.RegistryFactory;
import com.dfsek.terra.api.util.generic.pair.ImmutablePair; import com.dfsek.terra.api.util.generic.pair.ImmutablePair;
import com.dfsek.terra.api.util.reflection.ReflectionUtil; import com.dfsek.terra.api.util.reflection.ReflectionUtil;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider; import com.dfsek.terra.api.world.generator.ChunkGeneratorProvider;
import com.dfsek.terra.api.world.generator.GenerationStageProvider; import com.dfsek.terra.api.world.generator.GenerationStageProvider;
@@ -49,7 +49,6 @@ import com.dfsek.terra.registry.CheckedRegistryImpl;
import com.dfsek.terra.registry.OpenRegistryImpl; import com.dfsek.terra.registry.OpenRegistryImpl;
import com.dfsek.terra.registry.RegistryFactoryImpl; import com.dfsek.terra.registry.RegistryFactoryImpl;
import com.dfsek.terra.registry.config.ConfigTypeRegistry; import com.dfsek.terra.registry.config.ConfigTypeRegistry;
import com.dfsek.terra.world.TerraWorldImpl;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@@ -139,7 +138,7 @@ public class ConfigPackImpl implements ConfigPack {
main.logger().severe("Failed to load config pack from folder \"" + folder.getAbsolutePath() + "\""); main.logger().severe("Failed to load config pack from folder \"" + folder.getAbsolutePath() + "\"");
throw e; throw e;
} }
toWorldConfig(new TerraWorldImpl(new DummyWorld(), this, main)); // Build now to catch any errors immediately. toWorldConfig(new DummyWorld()); // Build now to catch any errors immediately.
} }
public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException { public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException {
@@ -192,19 +191,19 @@ public class ConfigPackImpl implements ConfigPack {
throw e; throw e;
} }
toWorldConfig(new TerraWorldImpl(new DummyWorld(), this, main)); // Build now to catch any errors immediately. toWorldConfig(new DummyWorld()); // Build now to catch any errors immediately.
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ConfigTypeRegistry createRegistry() { private ConfigTypeRegistry createRegistry() {
return new ConfigTypeRegistry(main, (id, configType) -> { return new ConfigTypeRegistry(main, (id, configType) -> {
OpenRegistry<?> openRegistry = configType.registrySupplier(this).get(); OpenRegistry<?> openRegistry = configType.registrySupplier(this).get();
if(registryMap.containsKey(configType.getTypeClass().getType())) { // Someone already registered something; we need to copy things to the new registry. if(registryMap.containsKey(configType.getTypeKey().getType())) { // Someone already registered something; we need to copy things to the new registry.
registryMap.get(configType.getTypeClass().getType()).getLeft().forEach(((OpenRegistry<Object>) openRegistry)::register); registryMap.get(configType.getTypeKey().getType()).getLeft().forEach(((OpenRegistry<Object>) openRegistry)::register);
} }
selfLoader.registerLoader(configType.getTypeClass().getType(), openRegistry); selfLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
abstractConfigLoader.registerLoader(configType.getTypeClass().getType(), openRegistry); abstractConfigLoader.registerLoader(configType.getTypeKey().getType(), openRegistry);
registryMap.put(configType.getTypeClass().getType(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry))); registryMap.put(configType.getTypeKey().getType(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry)));
}); });
} }
@@ -265,7 +264,7 @@ public class ConfigPackImpl implements ConfigPack {
} }
for(ConfigType<?, ?> configType : configTypeRegistry.entries()) { // Load the configs for(ConfigType<?, ?> configType : configTypeRegistry.entries()) { // Load the configs
CheckedRegistry registry = getCheckedRegistry(configType.getTypeClass()); CheckedRegistry registry = getCheckedRegistry(configType.getTypeKey());
main.getEventManager().callEvent(new ConfigTypePreLoadEvent(configType, registry, this)); main.getEventManager().callEvent(new ConfigTypePreLoadEvent(configType, registry, this));
for(AbstractConfiguration config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()))) { for(AbstractConfiguration config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()))) {
try { try {
@@ -353,7 +352,7 @@ public class ConfigPackImpl implements ConfigPack {
@Override @Override
public WorldConfigImpl toWorldConfig(TerraWorld world) { public WorldConfigImpl toWorldConfig(World world) {
return new WorldConfigImpl(world, this, main); return new WorldConfigImpl(world, this, main);
} }
@@ -1,9 +1,10 @@
package com.dfsek.terra.config.pack; package com.dfsek.terra.config.pack;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.config.WorldConfig; import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.SamplerCache; import com.dfsek.terra.api.world.generator.SamplerCache;
import com.dfsek.terra.registry.LockedRegistryImpl; import com.dfsek.terra.registry.LockedRegistryImpl;
@@ -18,12 +19,12 @@ public class WorldConfigImpl implements WorldConfig {
private final BiomeProvider provider; private final BiomeProvider provider;
private final TerraWorld world; private final World world;
private final ConfigPackImpl pack; private final ConfigPackImpl pack;
private final Map<Type, Registry<?>> registryMap = new HashMap<>(); private final Map<Type, Registry<?>> registryMap = new HashMap<>();
public WorldConfigImpl(TerraWorld world, ConfigPackImpl pack, TerraPlugin main) { public WorldConfigImpl(World world, ConfigPackImpl pack, TerraPlugin main) {
this.world = world; this.world = world;
this.pack = pack; this.pack = pack;
this.samplerCache = new SamplerCacheImpl(main, world); this.samplerCache = new SamplerCacheImpl(main, world);
@@ -40,7 +41,7 @@ public class WorldConfigImpl implements WorldConfig {
} }
@Override @Override
public TerraWorld getWorld() { public World getWorld() {
return world; return world;
} }
@@ -54,6 +55,11 @@ public class WorldConfigImpl implements WorldConfig {
return provider; return provider;
} }
@Override
public ConfigPack getPack() {
return pack;
}
@Override @Override
public int elevationBlend() { public int elevationBlend() {
return pack.getTemplate().getElevationBlend(); return pack.getTemplate().getElevationBlend();
@@ -22,7 +22,7 @@ public class ConfigTypeRegistry extends OpenRegistryImpl<ConfigType<?, ?>> {
@Override @Override
public boolean register(String identifier, Entry<ConfigType<?, ?>> value) { public boolean register(String identifier, Entry<ConfigType<?, ?>> value) {
callback.accept(identifier, value.getValue()); callback.accept(identifier, value.getValue());
main.getDebugLogger().info("Registered config registry with ID " + identifier + " to type " + ReflectionUtil.typeToString(value.getValue().getTypeClass().getType())); main.getDebugLogger().info("Registered config registry with ID " + identifier + " to type " + ReflectionUtil.typeToString(value.getValue().getTypeKey().getType()));
return super.register(identifier, value); return super.register(identifier, value);
} }
} }
@@ -2,7 +2,7 @@ package com.dfsek.terra.world;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.util.MathUtil; import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.Sampler; import com.dfsek.terra.api.world.generator.Sampler;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
@@ -13,14 +13,14 @@ import org.jetbrains.annotations.NotNull;
public class SamplerCacheImpl implements com.dfsek.terra.api.world.generator.SamplerCache { public class SamplerCacheImpl implements com.dfsek.terra.api.world.generator.SamplerCache {
private final LoadingCache<Long, Sampler> cache; private final LoadingCache<Long, Sampler> cache;
public SamplerCacheImpl(TerraPlugin main, TerraWorld world) { public SamplerCacheImpl(TerraPlugin main, World world) {
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache()) cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache())
.build(new CacheLoader<Long, Sampler>() { .build(new CacheLoader<>() {
@Override @Override
public Sampler load(@NotNull Long key) { public Sampler load(@NotNull Long key) {
int cx = (int) (key >> 32); int cx = (int) (key >> 32);
int cz = (int) key.longValue(); int cz = (int) key.longValue();
return world.getWorld().getTerraGenerator().createSampler(cx, cz, world.getBiomeProvider(), world.getWorld(), world.getConfig().elevationBlend()); return world.getGenerator().createSampler(cx, cz, world.getBiomeProvider(), world, world.getConfig().elevationBlend());
} }
}); });
} }
@@ -1,57 +0,0 @@
package com.dfsek.terra.world;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.event.events.world.TerraWorldLoadEvent;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.Palette;
import com.dfsek.terra.api.world.generator.Sampler;
import com.dfsek.terra.config.pack.WorldConfigImpl;
import net.jafama.FastMath;
public class TerraWorldImpl implements TerraWorld {
private final BiomeProvider provider;
private final WorldConfigImpl config;
private final World world;
public TerraWorldImpl(World w, ConfigPack c, TerraPlugin main) {
if(!w.isTerraWorld()) throw new IllegalArgumentException("World " + w + " is not a Terra World!");
this.world = w;
config = (WorldConfigImpl) c.toWorldConfig(this);
this.provider = config.getProvider();
main.getEventManager().callEvent(new TerraWorldLoadEvent(this, c));
}
@Override
public World getWorld() {
return world;
}
@Override
public BiomeProvider getBiomeProvider() {
return provider;
}
@Override
public WorldConfigImpl getConfig() {
return config;
}
@Override
public BlockState getUngeneratedBlock(int x, int y, int z) {
return world.getTerraGenerator().getBlock(world, x, y, z);
}
@Override
public BlockState getUngeneratedBlock(Vector3 v) {
return getUngeneratedBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
}
@@ -20,10 +20,7 @@ import com.dfsek.terra.api.lang.Language;
import com.dfsek.terra.api.profiler.Profiler; import com.dfsek.terra.api.profiler.Profiler;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
import com.dfsek.terra.bukkit.command.BukkitCommandAdapter; import com.dfsek.terra.bukkit.command.BukkitCommandAdapter;
import com.dfsek.terra.bukkit.command.FixChunkCommand; import com.dfsek.terra.bukkit.command.FixChunkCommand;
import com.dfsek.terra.bukkit.command.SaveDataCommand; import com.dfsek.terra.bukkit.command.SaveDataCommand;
@@ -35,7 +32,6 @@ import com.dfsek.terra.bukkit.listeners.PaperListener;
import com.dfsek.terra.bukkit.listeners.SpigotListener; import com.dfsek.terra.bukkit.listeners.SpigotListener;
import com.dfsek.terra.bukkit.util.PaperUtil; import com.dfsek.terra.bukkit.util.PaperUtil;
import com.dfsek.terra.bukkit.world.BukkitBiome; import com.dfsek.terra.bukkit.world.BukkitBiome;
import com.dfsek.terra.bukkit.world.BukkitWorld;
import com.dfsek.terra.commands.CommandUtil; import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.commands.TerraCommandManager; import com.dfsek.terra.commands.TerraCommandManager;
import com.dfsek.terra.config.GenericLoaders; import com.dfsek.terra.config.GenericLoaders;
@@ -49,7 +45,6 @@ import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry; import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.util.logging.DebugLogger; import com.dfsek.terra.util.logging.DebugLogger;
import com.dfsek.terra.util.logging.JavaLogger; import com.dfsek.terra.util.logging.JavaLogger;
import com.dfsek.terra.world.TerraWorldImpl;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -79,8 +74,7 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
else BUKKIT_VERSION = BukkitVersion.UNKNOWN; else BUKKIT_VERSION = BukkitVersion.UNKNOWN;
} }
private final Map<String, com.dfsek.terra.api.world.generator.TerraChunkGenerator> generatorMap = new HashMap<>(); private final Map<String, com.dfsek.terra.api.world.generator.ChunkGenerator> generatorMap = new HashMap<>();
private final Map<World, TerraWorld> worldMap = new HashMap<>();
private final Map<String, ConfigPack> worlds = new HashMap<>(); private final Map<String, ConfigPack> worlds = new HashMap<>();
private final Profiler profiler = new ProfilerImpl(); private final Profiler profiler = new ProfilerImpl();
private final ConfigRegistry registry = new ConfigRegistry(); private final ConfigRegistry registry = new ConfigRegistry();
@@ -98,14 +92,7 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
config.load(this); config.load(this);
LangUtil.load(config.getLanguage(), this); // Load language. LangUtil.load(config.getLanguage(), this); // Load language.
boolean succeed = registry.loadAll(this); boolean succeed = registry.loadAll(this);
Map<World, TerraWorld> newMap = new HashMap<>();
worldMap.forEach((world, tw) -> {
tw.getConfig().getSamplerCache().clear();
String packID = tw.getConfig().getID();
newMap.put(world, new TerraWorldImpl(world, registry.get(packID), this));
});
worldMap.clear();
worldMap.putAll(newMap);
return succeed; return succeed;
} }
@@ -253,17 +240,6 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
return checkedRegistry; return checkedRegistry;
} }
public TerraWorld getWorld(World world) {
BukkitWorld w = (BukkitWorld) world;
if(!w.isTerraWorld())
throw new IllegalArgumentException("Not a Terra world! " + w.getGenerator());
if(!worlds.containsKey(w.getName())) {
getLogger().warning("Unexpected world load detected: \"" + w.getName() + "\"");
return new TerraWorldImpl(w, ((TerraChunkGenerator) w.getGenerator().getHandle()).getConfigPack(), this);
}
return worldMap.computeIfAbsent(w, w2 -> new TerraWorldImpl(w, worlds.get(w.getName()), this));
}
@Override @Override
public Logger logger() { public Logger logger() {
return new JavaLogger(getLogger()); return new JavaLogger(getLogger());
@@ -0,0 +1,38 @@
package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
public class BukkitChunkData implements ChunkData {
private final ChunkGenerator.ChunkData delegate;
public BukkitChunkData(ChunkGenerator.ChunkData delegate) {
this.delegate = delegate;
}
@Override
public ChunkGenerator.ChunkData getHandle() {
return delegate;
}
@Override
public int getMaxHeight() {
return delegate.getMaxHeight();
}
@Override
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
delegate.setBlock(x, y, z, ((BukkitBlockState) blockState).getHandle());
}
@Override
public @NotNull BlockState getBlock(int x, int y, int z) {
return BukkitBlockState.newInstance(delegate.getBlockData(x, y, z));
}
}
@@ -1,51 +0,0 @@
package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
public class BukkitChunkGenerator implements com.dfsek.terra.api.world.generator.ChunkGenerator {
private final ChunkGenerator delegate;
public BukkitChunkGenerator(ChunkGenerator delegate) {
this.delegate = delegate;
}
@Override
public ChunkGenerator getHandle() {
return delegate;
}
public static class BukkitChunkData implements ChunkData {
private final ChunkGenerator.ChunkData delegate;
public BukkitChunkData(ChunkGenerator.ChunkData delegate) {
this.delegate = delegate;
}
@Override
public ChunkGenerator.ChunkData getHandle() {
return delegate;
}
@Override
public int getMaxHeight() {
return delegate.getMaxHeight();
}
@Override
public void setBlock(int x, int y, int z, @NotNull BlockState blockState) {
delegate.setBlock(x, y, z, ((BukkitBlockState) blockState).getHandle());
}
@Override
public @NotNull BlockState getBlock(int x, int y, int z) {
return BukkitBlockState.newInstance(delegate.getBlockData(x, y, z));
}
}
}
@@ -3,13 +3,12 @@ package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.generator.GeneratorWrapper; import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.bukkit.population.PopulationManager; import com.dfsek.terra.bukkit.population.PopulationManager;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.bukkit.world.BukkitBiomeGrid; import com.dfsek.terra.bukkit.world.BukkitBiomeGrid;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -20,19 +19,19 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper { public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGenerator implements GeneratorWrapper {
private static final Map<com.dfsek.terra.api.world.World, PopulationManager> popMap = new HashMap<>(); private static final Map<com.dfsek.terra.api.world.World, PopulationManager> popMap = new HashMap<>();
private final PopulationManager popMan; private final PopulationManager popMan;
private final TerraChunkGenerator delegate; private final ChunkGenerator delegate;
private final TerraPlugin main; private final TerraPlugin main;
private boolean needsLoad = true; private boolean needsLoad = true;
public BukkitChunkGeneratorWrapper(TerraChunkGenerator delegate) { public BukkitChunkGeneratorWrapper(ChunkGenerator delegate) {
this.delegate = delegate; this.delegate = delegate;
this.main = delegate.getMain(); this.main = delegate.getMain();
this.popMan = new PopulationManager(delegate, main); this.popMan = new PopulationManager(delegate, main);
@@ -51,7 +50,6 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
} }
public static synchronized void fixChunk(Chunk c) { public static synchronized void fixChunk(Chunk c) {
if(!c.getWorld().isTerraWorld()) throw new IllegalArgumentException();
popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld()); popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld());
} }
@@ -72,7 +70,7 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
com.dfsek.terra.api.world.World bukkitWorld = BukkitAdapter.adapt(world); com.dfsek.terra.api.world.World bukkitWorld = BukkitAdapter.adapt(world);
if(needsLoad) load(bukkitWorld); // Load population data for world. if(needsLoad) load(bukkitWorld); // Load population data for world.
delegate.generateBiomes(bukkitWorld, random, x, z, new BukkitBiomeGrid(biome)); delegate.generateBiomes(bukkitWorld, random, x, z, new BukkitBiomeGrid(biome));
return (ChunkData) delegate.generateChunkData(bukkitWorld, random, x, z, new BukkitChunkGenerator.BukkitChunkData(createChunkData(world))).getHandle(); return (ChunkData) delegate.generateChunkData(bukkitWorld, random, x, z, new BukkitChunkData(createChunkData(world))).getHandle();
} }
@Override @Override
@@ -106,7 +104,7 @@ public class BukkitChunkGeneratorWrapper extends ChunkGenerator implements Gener
} }
@Override @Override
public TerraChunkGenerator getHandle() { public ChunkGenerator getHandle() {
return delegate; return delegate;
} }
} }
@@ -1,7 +1,7 @@
package com.dfsek.terra.bukkit.generator; package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.api.world.generator.Chunkified; import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
@@ -11,9 +11,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.Random; import java.util.Random;
public class BukkitPopulatorWrapper extends BlockPopulator { public class BukkitPopulatorWrapper extends BlockPopulator {
private final TerraChunkGenerator delegate; private final ChunkGenerator delegate;
public BukkitPopulatorWrapper(TerraChunkGenerator delegate) { public BukkitPopulatorWrapper(ChunkGenerator delegate) {
this.delegate = delegate; this.delegate = delegate;
} }
@@ -2,7 +2,6 @@ package com.dfsek.terra.bukkit.listeners;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.config.WorldConfig; import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.Tree; import com.dfsek.terra.api.world.Tree;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
@@ -42,9 +41,7 @@ public class CommonListener implements Listener {
public void onSaplingGrow(StructureGrowEvent e) { public void onSaplingGrow(StructureGrowEvent e) {
if(e.isCancelled()) return; if(e.isCancelled()) return;
World bukkit = BukkitAdapter.adapt(e.getWorld()); World bukkit = BukkitAdapter.adapt(e.getWorld());
if(!bukkit.isTerraWorld()) return; WorldConfig c = bukkit.getConfig();
TerraWorld tw = main.getWorld(bukkit);
WorldConfig c = tw.getConfig();
if(c.isDisableSaplings()) return; if(c.isDisableSaplings()) return;
e.setCancelled(true); e.setCancelled(true);
Block block = e.getLocation().getBlock(); Block block = e.getLocation().getBlock();
@@ -2,7 +2,7 @@ package com.dfsek.terra.bukkit.listeners;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.structure.configured.ConfiguredStructure; import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.locate.AsyncStructureFinder; import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.world.population.items.TerraStructure; import com.dfsek.terra.world.population.items.TerraStructure;
@@ -19,13 +19,12 @@ public class PaperListener implements Listener {
@EventHandler @EventHandler
public void onStructureLocate(StructureLocateEvent e) { public void onStructureLocate(StructureLocateEvent e) {
if(!BukkitAdapter.adapt(e.getWorld()).isTerraWorld()) return;
String name = "minecraft:" + e.getType().getName(); String name = "minecraft:" + e.getType().getName();
main.getDebugLogger().info("Overriding structure location for \"" + name + "\""); main.getDebugLogger().info("Overriding structure location for \"" + name + "\"");
TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getWorld())); World w = BukkitAdapter.adapt(e.getWorld());
ConfiguredStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(tw.getConfig().getLocatable().get(name)); ConfiguredStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(tw.getConfig().getLocatable().get(name));
if(config != null) { if(config != null) {
AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getOrigin().toVector()), tw.getWorld(), 0, 500, location -> { AsyncStructureFinder finder = new AsyncStructureFinder(w.getBiomeProvider(), config, BukkitAdapter.adapt(e.getOrigin().toVector()), tw.getWorld(), 0, 500, location -> {
if(location != null) if(location != null)
e.setResult(BukkitAdapter.adapt(location).toLocation(e.getWorld())); e.setResult(BukkitAdapter.adapt(location).toLocation(e.getWorld()));
main.getDebugLogger().info("Location: " + location); main.getDebugLogger().info("Location: " + location);
@@ -2,7 +2,7 @@ package com.dfsek.terra.bukkit.listeners;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.structure.configured.ConfiguredStructure; import com.dfsek.terra.api.structure.configured.ConfiguredStructure;
import com.dfsek.terra.api.world.TerraWorld; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.locate.AsyncStructureFinder; import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.world.population.items.TerraStructure; import com.dfsek.terra.world.population.items.TerraStructure;
@@ -35,10 +35,9 @@ public class SpigotListener implements Listener {
Entity entity = e.getEntity(); Entity entity = e.getEntity();
if(e.getEntityType().equals(EntityType.ENDER_SIGNAL)) { if(e.getEntityType().equals(EntityType.ENDER_SIGNAL)) {
main.getDebugLogger().info("Detected Ender Signal..."); main.getDebugLogger().info("Detected Ender Signal...");
if(!BukkitAdapter.adapt(e.getEntity().getWorld()).isTerraWorld()) return; World w = BukkitAdapter.adapt(e.getEntity().getWorld());
TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getEntity().getWorld()));
EnderSignal signal = (EnderSignal) entity; EnderSignal signal = (EnderSignal) entity;
ConfiguredStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(tw.getConfig().getLocatable().get("STRONGHOLD")); ConfiguredStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(w.getConfig().getLocatable().get("STRONGHOLD"));
if(config != null) { if(config != null) {
main.getDebugLogger().info("Overriding Ender Signal..."); main.getDebugLogger().info("Overriding Ender Signal...");
AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getLocation().toVector()), tw.getWorld(), 0, 500, location -> { AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getLocation().toVector()), tw.getWorld(), 0, 500, location -> {
@@ -54,7 +53,6 @@ public class SpigotListener implements Listener {
@EventHandler @EventHandler
public void onCartographerChange(VillagerAcquireTradeEvent e) { public void onCartographerChange(VillagerAcquireTradeEvent e) {
if(!BukkitAdapter.adapt(e.getEntity().getWorld()).isTerraWorld()) return;
if(!(e.getEntity() instanceof Villager)) return; if(!(e.getEntity() instanceof Villager)) return;
if(((Villager) e.getEntity()).getProfession().equals(Villager.Profession.CARTOGRAPHER)) { if(((Villager) e.getEntity()).getProfession().equals(Villager.Profession.CARTOGRAPHER)) {
main.logger().severe("Prevented server crash by stopping Cartographer villager from spawning."); main.logger().severe("Prevented server crash by stopping Cartographer villager from spawning.");
@@ -66,7 +64,6 @@ public class SpigotListener implements Listener {
@EventHandler @EventHandler
public void onCartographerLevel(VillagerCareerChangeEvent e) { public void onCartographerLevel(VillagerCareerChangeEvent e) {
if(!BukkitAdapter.adapt(e.getEntity().getWorld()).isTerraWorld()) return;
if(e.getProfession().equals(Villager.Profession.CARTOGRAPHER)) { if(e.getProfession().equals(Villager.Profession.CARTOGRAPHER)) {
main.logger().severe("Prevented server crash by stopping Cartographer villager from spawning."); main.logger().severe("Prevented server crash by stopping Cartographer villager from spawning.");
main.logger().severe("Please upgrade to Paper, which has a StructureLocateEvent that fixes this issue"); main.logger().severe("Please upgrade to Paper, which has a StructureLocateEvent that fixes this issue");
@@ -5,7 +5,7 @@ import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.Chunkified; import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.bukkit.TerraBukkitPlugin; import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.bukkit.world.BukkitWorld; import com.dfsek.terra.bukkit.world.BukkitWorld;
@@ -22,11 +22,11 @@ import java.util.Random;
* Cursed management class for the horrors of Bukkit population * Cursed management class for the horrors of Bukkit population
*/ */
public class PopulationManager extends BlockPopulator { public class PopulationManager extends BlockPopulator {
private final TerraChunkGenerator generator; private final ChunkGenerator generator;
private final HashSet<ChunkCoordinate> needsPop = new HashSet<>(); private final HashSet<ChunkCoordinate> needsPop = new HashSet<>();
private final TerraPlugin main; private final TerraPlugin main;
public PopulationManager(TerraChunkGenerator generator, TerraPlugin main) { public PopulationManager(ChunkGenerator generator, TerraPlugin main) {
this.generator = generator; this.generator = generator;
this.main = main; this.main = main;
} }
@@ -7,9 +7,7 @@ import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.bukkit.BukkitEntity; import com.dfsek.terra.bukkit.BukkitEntity;
import com.dfsek.terra.bukkit.generator.BukkitChunkGenerator;
import com.dfsek.terra.bukkit.world.block.state.BukkitBlockEntity; import com.dfsek.terra.bukkit.world.block.state.BukkitBlockEntity;
import com.dfsek.terra.bukkit.world.entity.BukkitEntityType; import com.dfsek.terra.bukkit.world.entity.BukkitEntityType;
@@ -33,11 +31,6 @@ public class BukkitWorld implements World {
return delegate.getMaxHeight(); return delegate.getMaxHeight();
} }
@Override
public ChunkGenerator getGenerator() {
return new BukkitChunkGenerator(delegate.getGenerator());
}
public String getName() { public String getName() {
return delegate.getName(); return delegate.getName();
} }
@@ -25,9 +25,7 @@ import com.dfsek.terra.api.profiler.Profiler;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.exception.DuplicateEntryException; import com.dfsek.terra.api.registry.exception.DuplicateEntryException;
import com.dfsek.terra.api.util.generic.pair.Pair; import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.Tree; import com.dfsek.terra.api.world.Tree;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.commands.CommandUtil; import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.commands.TerraCommandManager; import com.dfsek.terra.commands.TerraCommandManager;
@@ -52,17 +50,13 @@ import com.dfsek.terra.registry.LockedRegistryImpl;
import com.dfsek.terra.registry.master.AddonRegistry; import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry; import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.util.logging.DebugLogger; import com.dfsek.terra.util.logging.DebugLogger;
import com.dfsek.terra.world.TerraWorldImpl;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.decorator.Decorator; import net.minecraft.world.gen.decorator.Decorator;
import net.minecraft.world.gen.decorator.NopeDecoratorConfig; import net.minecraft.world.gen.decorator.NopeDecoratorConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeature;
@@ -83,7 +77,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
public static final ConfiguredFeature<?, ?> POPULATOR_CONFIGURED_FEATURE = POPULATOR_FEATURE.configure(FeatureConfig.DEFAULT).decorate(Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE)); public static final ConfiguredFeature<?, ?> POPULATOR_CONFIGURED_FEATURE = POPULATOR_FEATURE.configure(FeatureConfig.DEFAULT).decorate(Decorator.NOPE.configure(NopeDecoratorConfig.INSTANCE));
private static TerraFabricPlugin instance; private static TerraFabricPlugin instance;
private final org.apache.logging.log4j.Logger log4jLogger = LogManager.getLogger(); private final org.apache.logging.log4j.Logger log4jLogger = LogManager.getLogger();
private final Map<DimensionType, Pair<ServerWorld, TerraWorld>> worldMap = new HashMap<>();
private final EventManager eventManager = new EventManagerImpl(this); private final EventManager eventManager = new EventManagerImpl(this);
private final GenericLoaders genericLoaders = new GenericLoaders(this); private final GenericLoaders genericLoaders = new GenericLoaders(this);
private final Profiler profiler = new ProfilerImpl(); private final Profiler profiler = new ProfilerImpl();
@@ -119,10 +112,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
return instance; return instance;
} }
public Map<DimensionType, Pair<ServerWorld, TerraWorld>> getWorldMap() {
return worldMap;
}
private ProtoBiome parseBiome(String id) throws LoadException { private ProtoBiome parseBiome(String id) throws LoadException {
Identifier identifier = Identifier.tryParse(id); Identifier identifier = Identifier.tryParse(id);
if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier); // failure. if(BuiltinRegistries.BIOME.get(identifier) == null) throw new LoadException("Invalid Biome ID: " + identifier); // failure.
@@ -138,17 +127,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
return worldHandle; return worldHandle;
} }
@Override
public TerraWorld getWorld(World world) {
return getWorld(((WorldAccess) world).getDimension());
}
public TerraWorld getWorld(DimensionType type) {
TerraWorld world = worldMap.get(type).getRight();
if(world == null) throw new IllegalArgumentException("No world exists with dimension type " + type);
return world;
}
@Override @Override
public Logger logger() { public Logger logger() {
return logger; return logger;
@@ -188,11 +166,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
config.load(this); config.load(this);
LangUtil.load(config.getLanguage(), this); // Load language. LangUtil.load(config.getLanguage(), this); // Load language.
boolean succeed = configRegistry.loadAll(this); boolean succeed = configRegistry.loadAll(this);
worldMap.forEach((seed, pair) -> {
pair.getRight().getConfig().getSamplerCache().clear();
String packID = pair.getRight().getConfig().getID();
pair.setRight(new TerraWorldImpl(pair.getRight().getWorld(), configRegistry.get(packID), this));
});
return succeed; return succeed;
} }
@@ -1,12 +1,11 @@
package com.dfsek.terra.fabric.generation; package com.dfsek.terra.fabric.generation;
import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.ChunkData; import com.dfsek.terra.api.world.generator.ChunkData;
import com.dfsek.terra.api.world.generator.Chunkified; import com.dfsek.terra.api.world.generator.Chunkified;
import com.dfsek.terra.api.world.generator.GeneratorWrapper; import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.fabric.TerraFabricPlugin; import com.dfsek.terra.fabric.TerraFabricPlugin;
import com.dfsek.terra.fabric.block.FabricBlockState; import com.dfsek.terra.fabric.block.FabricBlockState;
import com.dfsek.terra.fabric.mixin.StructureAccessorAccessor; import com.dfsek.terra.fabric.mixin.StructureAccessorAccessor;
@@ -29,11 +28,9 @@ import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.SpawnSettings; import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.biome.source.BiomeAccess; import net.minecraft.world.biome.source.BiomeAccess;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.ChunkRandom; import net.minecraft.world.gen.ChunkRandom;
import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.StructureAccessor; import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.StructuresConfig; import net.minecraft.world.gen.chunk.StructuresConfig;
import net.minecraft.world.gen.chunk.VerticalBlockSample; import net.minecraft.world.gen.chunk.VerticalBlockSample;
import net.minecraft.world.gen.feature.StructureFeature; import net.minecraft.world.gen.feature.StructureFeature;
@@ -42,7 +39,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
public class FabricChunkGeneratorWrapper extends ChunkGenerator implements GeneratorWrapper { public class FabricChunkGeneratorWrapper extends net.minecraft.world.gen.chunk.ChunkGenerator implements GeneratorWrapper {
public static final Codec<ConfigPack> PACK_CODEC = RecordCodecBuilder.create( public static final Codec<ConfigPack> PACK_CODEC = RecordCodecBuilder.create(
config -> config.group( config -> config.group(
Codec.STRING.fieldOf("pack") Codec.STRING.fieldOf("pack")
@@ -61,11 +58,11 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
); );
private final long seed; private final long seed;
private final TerraChunkGenerator delegate; private final ChunkGenerator delegate;
private final TerraBiomeSource biomeSource; private final TerraBiomeSource biomeSource;
private final ConfigPack pack; private final ConfigPack pack;
private DimensionType dimensionType; private ServerWorld world;
public FabricChunkGeneratorWrapper(TerraBiomeSource biomeSource, long seed, ConfigPack configPack) { public FabricChunkGeneratorWrapper(TerraBiomeSource biomeSource, long seed, ConfigPack configPack) {
super(biomeSource, new StructuresConfig(false)); super(biomeSource, new StructuresConfig(false));
@@ -80,12 +77,12 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
@Override @Override
protected Codec<? extends ChunkGenerator> getCodec() { protected Codec<? extends net.minecraft.world.gen.chunk.ChunkGenerator> getCodec() {
return CODEC; return CODEC;
} }
@Override @Override
public ChunkGenerator withSeed(long seed) { public net.minecraft.world.gen.chunk.ChunkGenerator withSeed(long seed) {
return new FabricChunkGeneratorWrapper((TerraBiomeSource) this.biomeSource.withSeed(seed), seed, pack); return new FabricChunkGeneratorWrapper((TerraBiomeSource) this.biomeSource.withSeed(seed), seed, pack);
} }
@@ -98,8 +95,8 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
// No-op // No-op
} }
public void setDimensionType(DimensionType dimensionType) { public void setWorld(ServerWorld world) {
this.dimensionType = dimensionType; this.world = world;
} }
@Nullable @Nullable
@@ -170,9 +167,8 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
@Override @Override
public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView heightmapType) { public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView heightmapType) {
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(dimensionType); int height = ((World) world).getMaxHeight();
int height = world.getWorld().getMaxHeight(); while(height >= ((World) world).getMinHeight() && !heightmap.getBlockPredicate().test(((FabricBlockState) ((World) world).getGenerator().getBlock((World) world, x, height - 1, z)).getHandle())) {
while(height >= world.getWorld().getMinHeight() && !heightmap.getBlockPredicate().test(((FabricBlockState) world.getUngeneratedBlock(x, height - 1, z)).getHandle())) {
height--; height--;
} }
return height; return height;
@@ -180,10 +176,9 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
@Override @Override
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView view) { public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView view) {
TerraWorld world = TerraFabricPlugin.getInstance().getWorld(dimensionType);
BlockState[] array = new BlockState[view.getHeight()]; BlockState[] array = new BlockState[view.getHeight()];
for(int y = view.getBottomY() + view.getHeight() - 1; y >= view.getBottomY(); y--) { for(int y = view.getBottomY() + view.getHeight() - 1; y >= view.getBottomY(); y--) {
array[y] = ((FabricBlockState) world.getUngeneratedBlock(x, y, z)).getHandle(); array[y] = ((FabricBlockState) ((World) world).getGenerator().getBlock((World) world, x, y, z)).getHandle();
} }
return new VerticalBlockSample(view.getBottomY(), array); return new VerticalBlockSample(view.getBottomY(), array);
} }
@@ -229,7 +224,7 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
} }
@Override @Override
public TerraChunkGenerator getHandle() { public ChunkGenerator getHandle() {
return delegate; return delegate;
} }
} }
@@ -56,4 +56,8 @@ public class TerraBiomeSource extends BiomeSource {
TerraBiome biome = provider.getBiome(biomeX << 2, biomeZ << 2, seed); TerraBiome biome = provider.getBiome(biomeX << 2, biomeZ << 2, seed);
return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID()))); return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID())));
} }
public BiomeProvider getProvider() {
return provider;
}
} }
@@ -1,9 +1,7 @@
package com.dfsek.terra.fabric.mixin; package com.dfsek.terra.fabric.mixin;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.fabric.TerraFabricPlugin; import com.dfsek.terra.fabric.TerraFabricPlugin;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper; import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.world.TerraWorldImpl;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener; import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
@@ -27,9 +25,8 @@ public abstract class ServerWorldMixin {
@Inject(method = "<init>", at = @At(value = "RETURN")) @Inject(method = "<init>", at = @At(value = "RETURN"))
public void injectConstructor(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<World> registryKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo ci) { public void injectConstructor(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<World> registryKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long l, List<Spawner> list, boolean bl, CallbackInfo ci) {
if(chunkGenerator instanceof FabricChunkGeneratorWrapper) { if(chunkGenerator instanceof FabricChunkGeneratorWrapper) {
TerraFabricPlugin.getInstance().getWorldMap().put(dimensionType, Pair.of((ServerWorld) (Object) this, new TerraWorldImpl((com.dfsek.terra.api.world.World) this, ((FabricChunkGeneratorWrapper) chunkGenerator).getPack(), TerraFabricPlugin.getInstance()))); ((FabricChunkGeneratorWrapper) chunkGenerator).setWorld((ServerWorld) (Object) this);
((FabricChunkGeneratorWrapper) chunkGenerator).setDimensionType(dimensionType); TerraFabricPlugin.getInstance().logger().info("Registered world " + this);
TerraFabricPlugin.getInstance().logger().info("Registered world " + this + " to dimension type " + dimensionType);
} }
} }
} }
@@ -1,16 +0,0 @@
package com.dfsek.terra.fabric.mixin.implementations;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ChunkGenerator.class)
@Implements(@Interface(iface = com.dfsek.terra.api.world.generator.ChunkGenerator.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ChunkGeneratorMixin {
@Intrinsic
public Object terra$getHandle() {
return this;
}
}
@@ -9,7 +9,9 @@ import com.dfsek.terra.api.world.World;
import com.dfsek.terra.fabric.TerraFabricPlugin; import com.dfsek.terra.fabric.TerraFabricPlugin;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeature;
import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Implements;
@@ -32,7 +34,7 @@ public abstract class ConfiguredFeatureMixin {
String id = BuiltinRegistries.CONFIGURED_FEATURE.getId((ConfiguredFeature<?, ?>) (Object) this).toString(); String id = BuiltinRegistries.CONFIGURED_FEATURE.getId((ConfiguredFeature<?, ?>) (Object) this).toString();
try(ProfileFrame ignore = TerraFabricPlugin.getInstance().getProfiler().profile("fabric_tree:" + id.toLowerCase(Locale.ROOT))) { try(ProfileFrame ignore = TerraFabricPlugin.getInstance().getProfiler().profile("fabric_tree:" + id.toLowerCase(Locale.ROOT))) {
StructureWorldAccess fabricWorldAccess = ((StructureWorldAccess) world); StructureWorldAccess fabricWorldAccess = ((StructureWorldAccess) world);
ChunkGenerator generatorWrapper = (ChunkGenerator) world.getGenerator(); ChunkGenerator generatorWrapper = ((ServerWorldAccess) world).toServerWorld().getChunkManager().getChunkGenerator();
return generate(fabricWorldAccess, generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ())); return generate(fabricWorldAccess, generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()));
} }
} }
@@ -2,16 +2,17 @@ package com.dfsek.terra.fabric.mixin.implementations.world;
import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
import com.dfsek.terra.fabric.block.FabricBlockState; import com.dfsek.terra.fabric.block.FabricBlockState;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper; import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
import com.dfsek.terra.fabric.util.FabricUtil; import com.dfsek.terra.fabric.util.FabricUtil;
import net.minecraft.block.FluidBlock; import net.minecraft.block.FluidBlock;
import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluid;
@@ -21,16 +22,24 @@ import net.minecraft.world.ChunkRegion;
import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.TickScheduler; import net.minecraft.world.TickScheduler;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
import net.minecraft.world.chunk.ChunkStatus;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(ChunkRegion.class) @Mixin(ChunkRegion.class)
@Implements(@Interface(iface = World.class, prefix = "terraWorld$", remap = Interface.Remap.NONE)) @Implements(@Interface(iface = World.class, prefix = "terraWorld$", remap = Interface.Remap.NONE))
public abstract class ChunkRegionMixin { public abstract class ChunkRegionMixin {
private WorldConfig config;
@Shadow @Shadow
@Final @Final
private ServerWorld world; private ServerWorld world;
@@ -39,9 +48,6 @@ public abstract class ChunkRegionMixin {
@Final @Final
private long seed; private long seed;
@Shadow
public abstract boolean setBlockState(BlockPos pos, net.minecraft.block.BlockState state, int flags, int maxUpdateDepth);
@Shadow @Shadow
public abstract TickScheduler<Fluid> getFluidTickScheduler(); public abstract TickScheduler<Fluid> getFluidTickScheduler();
@@ -49,9 +55,9 @@ public abstract class ChunkRegionMixin {
return (((ChunkRegion) (Object) this).getBottomY()) + ((ChunkRegion) (Object) this).getHeight(); return (((ChunkRegion) (Object) this).getBottomY()) + ((ChunkRegion) (Object) this).getHeight();
} }
@SuppressWarnings("deprecation") @Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/server/world/ServerWorld;Ljava/util/List;Lnet/minecraft/world/chunk/ChunkStatus;I)V")
public ChunkGenerator terraWorld$getGenerator() { public void injectConstructor(ServerWorld world, List<net.minecraft.world.chunk.Chunk> list, ChunkStatus chunkStatus, int i, CallbackInfo ci) {
return (ChunkGenerator) ((ChunkRegion) (Object) this).toServerWorld().getChunkManager().getChunkGenerator(); this.config = ((World) world).getConfig();
} }
public Chunk terraWorld$getChunkAt(int x, int z) { public Chunk terraWorld$getChunkAt(int x, int z) {
@@ -99,12 +105,17 @@ public abstract class ChunkRegionMixin {
return this; return this;
} }
public boolean terraWorld$isTerraWorld() { public ChunkGenerator terraWorld$getGenerator() {
return terraWorld$getGenerator() instanceof GeneratorWrapper; return ((FabricChunkGeneratorWrapper) world.getChunkManager().getChunkGenerator()).getHandle();
} }
public TerraChunkGenerator terraWorld$getTerraGenerator() { @SuppressWarnings("deprecation")
return ((FabricChunkGeneratorWrapper) terraWorld$getGenerator()).getHandle(); public BiomeProvider terraWorld$getBiomeProvider() {
return ((TerraBiomeSource) ((ChunkRegion) (Object) this).toServerWorld().getChunkManager().getChunkGenerator().getBiomeSource()).getProvider();
}
public WorldConfig terraWorld$getConfig() {
return config;
} }
/** /**
@@ -2,39 +2,63 @@ package com.dfsek.terra.fabric.mixin.implementations.world;
import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.WorldConfig;
import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.generator.ChunkGenerator; import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
import com.dfsek.terra.fabric.block.FabricBlockState; import com.dfsek.terra.fabric.block.FabricBlockState;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper; import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
import com.dfsek.terra.fabric.util.FabricUtil; import com.dfsek.terra.fabric.util.FabricUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.server.world.ServerChunkManager;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.Spawner;
import net.minecraft.world.level.ServerWorldProperties;
import net.minecraft.world.level.storage.LevelStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.concurrent.Executor;
@Mixin(ServerWorld.class) @Mixin(ServerWorld.class)
@Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE)) @Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ServerWorldMixin { public abstract class ServerWorldMixin {
private WorldConfig config;
@Shadow @Shadow
public abstract long getSeed(); public abstract long getSeed();
public int terra$getMaxHeight() { @Shadow
return (((ServerWorld) (Object) this).getBottomY()) + ((ServerWorld) (Object) this).getHeight(); @Final
private ServerChunkManager chunkManager;
@Inject(at = @At("RETURN"), method = "<init>(Lnet/minecraft/server/MinecraftServer;Ljava/util/concurrent/Executor;Lnet/minecraft/world/level/storage/LevelStorage$Session;Lnet/minecraft/world/level/ServerWorldProperties;Lnet/minecraft/util/registry/RegistryKey;Lnet/minecraft/world/dimension/DimensionType;Lnet/minecraft/server/WorldGenerationProgressListener;Lnet/minecraft/world/gen/chunk/ChunkGenerator;ZJLjava/util/List;Z)V")
public void injectConstructor(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<net.minecraft.world.World> worldKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, net.minecraft.world.gen.chunk.ChunkGenerator chunkGenerator, boolean debugWorld, long seed, List<Spawner> spawners, boolean shouldTickTime, CallbackInfo ci) {
if(chunkGenerator instanceof FabricChunkGeneratorWrapper) {
config = ((FabricChunkGeneratorWrapper) chunkGenerator).getPack().toWorldConfig((World) this);
}
} }
public ChunkGenerator terra$getGenerator() { public int terra$getMaxHeight() {
return (ChunkGenerator) ((ServerWorld) (Object) this).getChunkManager().getChunkGenerator(); return (((ServerWorld) (Object) this).getBottomY()) + ((ServerWorld) (Object) this).getHeight();
} }
public Chunk terra$getChunkAt(int x, int z) { public Chunk terra$getChunkAt(int x, int z) {
@@ -75,12 +99,16 @@ public abstract class ServerWorldMixin {
return this; return this;
} }
public boolean terra$isTerraWorld() { public ChunkGenerator terra$getGenerator() {
return terra$getGenerator() instanceof GeneratorWrapper; return ((FabricChunkGeneratorWrapper) chunkManager.getChunkGenerator()).getHandle();
} }
public TerraChunkGenerator terra$getTerraGenerator() { public BiomeProvider terra$getBiomeProvider() {
return ((FabricChunkGeneratorWrapper) terra$getGenerator()).getHandle(); return ((TerraBiomeSource) ((ServerWorld) (Object) this).getChunkManager().getChunkGenerator().getBiomeSource()).getProvider();
}
public WorldConfig terra$getConfig() {
return config;
} }
/** /**
@@ -11,7 +11,6 @@
"access.MobSpawnerLogicAccessor", "access.MobSpawnerLogicAccessor",
"access.StateAccessor", "access.StateAccessor",
"implementations.BiomeMixin", "implementations.BiomeMixin",
"implementations.ChunkGeneratorMixin",
"implementations.ConfiguredFeatureMixin", "implementations.ConfiguredFeatureMixin",
"implementations.block.BlockEntityMixin", "implementations.block.BlockEntityMixin",
"implementations.block.BlockMixin", "implementations.block.BlockMixin",
File renamed without changes.
@@ -1,8 +1,6 @@
package com.dfsek.terra; package com.dfsek.terra;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.tectonic.loading.TypeRegistry; import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addon.TerraAddon; import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.BlockState;
@@ -15,9 +13,6 @@ import com.dfsek.terra.api.lang.Language;
import com.dfsek.terra.api.profiler.Profiler; import com.dfsek.terra.api.profiler.Profiler;
import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.tectonic.LoaderHolder;
import com.dfsek.terra.api.world.TerraWorld;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.config.GenericLoaders; import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfigImpl; import com.dfsek.terra.config.PluginConfigImpl;
@@ -33,12 +28,9 @@ import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry; import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.util.logging.DebugLogger; import com.dfsek.terra.util.logging.DebugLogger;
import com.dfsek.terra.util.logging.JavaLogger; import com.dfsek.terra.util.logging.JavaLogger;
import com.dfsek.terra.world.TerraWorldImpl;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type;
import java.util.function.Supplier;
import java.util.logging.Logger; import java.util.logging.Logger;
public class StandalonePlugin implements TerraPlugin { public class StandalonePlugin implements TerraPlugin {
@@ -58,11 +50,6 @@ public class StandalonePlugin implements TerraPlugin {
return worldHandle; return worldHandle;
} }
@Override
public TerraWorld getWorld(World world) {
return new TerraWorldImpl(world, registry.get("DEFAULT"), this);
}
@Override @Override
public com.dfsek.terra.api.Logger logger() { public com.dfsek.terra.api.Logger logger() {
return new JavaLogger(Logger.getLogger("Terra")); return new JavaLogger(Logger.getLogger("Terra"));
@@ -8,7 +8,6 @@ import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.vector.Vector3; import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk; import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World; import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.ChunkGenerator;
import net.jafama.FastMath; import net.jafama.FastMath;
import net.querz.mca.MCAFile; import net.querz.mca.MCAFile;
import net.querz.mca.MCAUtil; import net.querz.mca.MCAUtil;
@@ -25,7 +24,7 @@ public class DirectWorld implements World {
private final GenWrapper generator; private final GenWrapper generator;
private final Map<Long, MCAFile> files = Collections.synchronizedMap(new HashMap<>()); private final Map<Long, MCAFile> files = Collections.synchronizedMap(new HashMap<>());
public DirectWorld(long seed, GenWrapper generator) { public DirectWorld(long seed) {
this.seed = seed; this.seed = seed;
this.generator = generator; this.generator = generator;
} }
@@ -40,11 +39,6 @@ public class DirectWorld implements World {
return 255; return 255;
} }
@Override
public ChunkGenerator getGenerator() {
return generator;
}
@Override @Override
public Chunk getChunkAt(int x, int z) { public Chunk getChunkAt(int x, int z) {
MCAFile file = compute(x, z); MCAFile file = compute(x, z);
@@ -1,18 +0,0 @@
package com.dfsek.terra.platform;
import com.dfsek.terra.api.world.generator.ChunkGenerator;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
public class GenWrapper implements ChunkGenerator {
private final TerraChunkGenerator generator;
public GenWrapper(TerraChunkGenerator generator) {
this.generator = generator;
}
@Override
public Object getHandle() {
return generator;
}
}
@@ -4,7 +4,6 @@ import com.dfsek.terra.StandalonePlugin;
import com.dfsek.terra.api.world.generator.TerraChunkGenerator; import com.dfsek.terra.api.world.generator.TerraChunkGenerator;
import com.dfsek.terra.platform.DirectChunkData; import com.dfsek.terra.platform.DirectChunkData;
import com.dfsek.terra.platform.DirectWorld; import com.dfsek.terra.platform.DirectWorld;
import com.dfsek.terra.platform.GenWrapper;
import net.querz.mca.MCAFile; import net.querz.mca.MCAFile;
import net.querz.mca.MCAUtil; import net.querz.mca.MCAUtil;
@@ -28,8 +27,7 @@ public class Generator {
System.out.println("Total mem: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024 + "GB"); System.out.println("Total mem: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024 + "GB");
GenWrapper wrapper = new GenWrapper(generator); DirectWorld world = new DirectWorld(seed, null);
DirectWorld world = new DirectWorld(seed, wrapper);
long l = System.nanoTime(); long l = System.nanoTime();
int count = 0; int count = 0;
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more