begin work on WorldConfig stuff

This doesn't compile right now. A lot of work needs to be done.
This commit is contained in:
dfsek 2021-03-01 09:58:18 -07:00
parent 7f988dcf26
commit 5a6b7ac4c1
32 changed files with 377 additions and 152 deletions

View File

@ -1,13 +1,15 @@
package com.dfsek.terra.api.event.events.world; package com.dfsek.terra.api.event.events.world;
import com.dfsek.terra.api.event.events.Event;
import com.dfsek.terra.api.event.events.PackEvent; import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.TerraWorld;
/** /**
* Called upon initialization of a TerraWorld. * Called upon initialization of a TerraWorld.
*/ */
public class TerraWorldLoadEvent implements PackEvent { public class TerraWorldLoadEvent implements Event {
private final TerraWorld world; private final TerraWorld world;
public TerraWorldLoadEvent(TerraWorld world) { public TerraWorldLoadEvent(TerraWorld world) {
@ -18,8 +20,7 @@ public class TerraWorldLoadEvent implements PackEvent {
return world; return world;
} }
@Override public WorldConfig getPack() {
public ConfigPack getPack() {
return world.getConfig(); return world.getConfig();
} }
} }

View File

@ -15,9 +15,9 @@ import java.util.function.Consumer;
* @param <T> Type in registry * @param <T> Type in registry
*/ */
public class LockedRegistry<T> implements Registry<T> { public class LockedRegistry<T> implements Registry<T> {
private final OpenRegistry<T> registry; private final Registry<T> registry;
public LockedRegistry(OpenRegistry<T> registry) { public LockedRegistry(Registry<T> registry) {
this.registry = registry; this.registry = registry;
} }

View File

@ -31,7 +31,6 @@ import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
import com.dfsek.terra.registry.config.FunctionRegistry; import com.dfsek.terra.registry.config.FunctionRegistry;
import com.dfsek.terra.registry.config.LootRegistry; import com.dfsek.terra.registry.config.LootRegistry;
import com.dfsek.terra.registry.config.ScriptRegistry; import com.dfsek.terra.registry.config.ScriptRegistry;
import com.dfsek.terra.world.generation.math.SamplerCache;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import net.jafama.FastMath; import net.jafama.FastMath;
@ -49,7 +48,7 @@ public class StructureScript {
private final TerraPlugin main; private final TerraPlugin main;
private String tempID; private String tempID;
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache, FunctionRegistry functionRegistry) throws ParseException { public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, FunctionRegistry functionRegistry) throws ParseException {
Parser parser; Parser parser;
try { try {
parser = new Parser(IOUtils.toString(inputStream)); parser = new Parser(IOUtils.toString(inputStream));
@ -60,7 +59,7 @@ public class StructureScript {
functionRegistry.forEach(parser::registerFunction); // Register registry functions. functionRegistry.forEach(parser::registerFunction); // Register registry functions.
parser.registerFunction("block", new BlockFunctionBuilder(main)) parser.registerFunction("block", new BlockFunctionBuilder(main))
.registerFunction("check", new CheckFunctionBuilder(main, cache)) .registerFunction("check", new CheckFunctionBuilder(main))
.registerFunction("structure", new StructureFunctionBuilder(registry, main)) .registerFunction("structure", new StructureFunctionBuilder(registry, main))
.registerFunction("randomInt", new RandomFunctionBuilder()) .registerFunction("randomInt", new RandomFunctionBuilder())
.registerFunction("recursions", new RecursionsFunctionBuilder()) .registerFunction("recursions", new RecursionsFunctionBuilder())

View File

@ -12,17 +12,15 @@ import java.util.List;
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> { public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
private final TerraPlugin main; private final TerraPlugin main;
private final SamplerCache cache;
public CheckFunctionBuilder(TerraPlugin main, SamplerCache cache) { public CheckFunctionBuilder(TerraPlugin main) {
this.main = main; this.main = main;
this.cache = cache;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public CheckFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException { public CheckFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new CheckFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), cache, position); return new CheckFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
} }
@Override @Override

View File

@ -25,22 +25,23 @@ public class CheckFunction implements Function<String> {
private final TerraPlugin main; private final TerraPlugin main;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
private final SamplerCache cache;
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, SamplerCache cache, Position position) { public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.main = main; this.main = main;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.position = position; this.position = position;
this.cache = cache;
} }
@Override @Override
public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) { public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
@ -52,7 +53,8 @@ public class CheckFunction implements Function<String> {
private String apply(Location vector, World world) { private String apply(Location vector, World world) {
TerraWorld tw = main.getWorld(world); TerraWorld tw = main.getWorld(world);
double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), world); SamplerCache cache = tw.getConfig().getSamplerCache();
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.
@ -64,10 +66,10 @@ public class CheckFunction implements Function<String> {
return "OCEAN"; // Below sea level return "OCEAN"; // Below sea level
} }
private double sample(int x, int y, int z, World w) { private double sample(int x, int y, int z, SamplerCache cache) {
int cx = FastMath.floorDiv(x, 16); int cx = FastMath.floorDiv(x, 16);
int cz = FastMath.floorDiv(z, 16); int cz = FastMath.floorDiv(z, 16);
return cache.get(w, x, z).sample(x - (cx << 4), y, z - (cz << 4)); return cache.get(x, z).sample(x - (cx << 4), y, z - (cz << 4));
} }
@Override @Override

View File

@ -5,6 +5,7 @@ import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.collections.ProbabilityCollection; import com.dfsek.terra.api.util.collections.ProbabilityCollection;
import com.dfsek.terra.config.builder.GeneratorBuilder; import com.dfsek.terra.config.builder.GeneratorBuilder;
import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.generation.WorldGenerator;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -13,7 +14,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 GeneratorBuilder gen; private final WorldGenerator 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;
@ -21,13 +22,13 @@ public class UserDefinedBiome implements TerraBiome {
private final Set<String> tags; private final Set<String> tags;
public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, GeneratorBuilder gen, BiomeTemplate config) { public UserDefinedBiome(ProbabilityCollection<Biome> vanilla, WorldGenerator gen, BiomeTemplate config) {
this.vanilla = vanilla; this.vanilla = vanilla;
this.gen = gen; this.gen = gen;
this.id = config.getID(); this.id = config.getID();
this.config = config; this.config = config;
this.color = config.getColor(); this.color = config.getColor();
this.tags = config.getTags() == null ? new HashSet<>() : config.getTags(); this.tags = config.getTags();
tags.add("BIOME:" + id); tags.add("BIOME:" + id);
} }
@ -52,7 +53,7 @@ public class UserDefinedBiome implements TerraBiome {
@Override @Override
public Generator getGenerator(World w) { public Generator getGenerator(World w) {
return gen.build(w.getSeed()); return gen;
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.api.world.biome.provider; package com.dfsek.terra.api.world.biome.provider;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
import net.jafama.FastMath; import net.jafama.FastMath;
@ -15,7 +16,7 @@ public class ImageBiomeProvider implements BiomeProvider, BiomeProvider.BiomePro
private final int resolution; private final int resolution;
private final Align align; private final Align align;
public ImageBiomeProvider(OpenRegistry<TerraBiome> registry, BufferedImage image, int resolution, Align align) { public ImageBiomeProvider(Registry<TerraBiome> registry, BufferedImage image, int resolution, Align align) {
this.image = image; this.image = image;
this.resolution = resolution; this.resolution = resolution;
this.align = align; this.align = align;

View File

@ -0,0 +1,57 @@
package com.dfsek.terra.config.builder;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.ExpressionSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.generation.WorldGenerator;
import java.util.HashMap;
import java.util.Map;
public class BiomeBuilder implements ConfigBuilder<TerraBiome> {
private final BiomeTemplate template;
private final ConfigPack pack;
public BiomeBuilder(BiomeTemplate template, ConfigPack pack) {
this.template = template;
this.pack = pack;
}
@Override
public TerraBiome build(TerraWorld world, TerraPlugin main) {
NoiseSampler noise;
NoiseSampler elevation;
NoiseSampler carving;
Scope varScope = new Scope().withParent(pack.getVarScope());
template.getVariables().forEach(varScope::create);
Map<String, NoiseSeeded> noiseBuilderMap = pack.getTemplate().getNoiseBuilderMap();
Map<String, FunctionTemplate> functionTemplateMap = new HashMap<>(template.getFunctions());
functionTemplateMap.putAll(template.getFunctions());
long seed = world.getWorld().getSeed();
try {
noise = new ExpressionSampler(template.getNoiseEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
elevation = template.getElevationEquation() == null ? new ConstantSampler(0) : new ExpressionSampler(template.getElevationEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
carving = new ExpressionSampler(template.getCarvingEquation(), varScope, seed, noiseBuilderMap, functionTemplateMap);
} catch(ParseException e) {
throw new RuntimeException(e);
}
WorldGenerator generator = new WorldGenerator(template.getPalette(), template.getSlantPalette(), noise, elevation, carving, template.getBiomeNoise().apply(seed), template.getElevationWeight(),
template.getBlendDistance(), template.getBlendStep(), template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generator, template);
}
}

View File

@ -0,0 +1,8 @@
package com.dfsek.terra.config.builder;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.world.TerraWorld;
public interface ConfigBuilder<O> {
O build(TerraWorld world, TerraPlugin main);
}

View File

@ -0,0 +1,12 @@
package com.dfsek.terra.config.builder;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.world.TerraWorld;
public class ScriptBuilder implements ConfigBuilder<StructureScript> {
@Override
public StructureScript build(TerraWorld world, TerraPlugin main) {
return null;
}
}

View File

@ -0,0 +1,79 @@
package com.dfsek.terra.config.dummy;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.platform.world.generator.ChunkGenerator;
import java.io.File;
import java.util.UUID;
public class DummyWorld implements World {
@Override
public Object getHandle() {
throw new UnsupportedOperationException("Cannot get handle of DummyWorld");
}
@Override
public long getSeed() {
return 2403L;
}
@Override
public int getMaxHeight() {
return 155;
}
@Override
public ChunkGenerator getGenerator() {
throw new UnsupportedOperationException("Cannot get generator of DummyWorld");
}
@Override
public String getName() {
return "DUMMY";
}
@Override
public UUID getUID() {
return UUID.randomUUID();
}
@Override
public boolean isChunkGenerated(int x, int z) {
return false;
}
@Override
public Chunk getChunkAt(int x, int z) {
throw new UnsupportedOperationException("Cannot get chunk in DummyWorld");
}
@Override
public File getWorldFolder() {
throw new UnsupportedOperationException("Cannot get folder of DummyWorld");
}
@Override
public Block getBlockAt(int x, int y, int z) {
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
}
@Override
public Block getBlockAt(Location l) {
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
throw new UnsupportedOperationException("Cannot spawn entity in DummyWorld");
}
@Override
public int getMinHeight() {
return 0;
}
}

View File

@ -1,18 +1,13 @@
package com.dfsek.terra.config.factories; package com.dfsek.terra.config.factories;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome; import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.builder.GeneratorBuilder; import com.dfsek.terra.config.builder.ConfigBuilder;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.templates.BiomeTemplate;
import java.util.LinkedHashMap; public class BiomeFactory implements ConfigFactory<BiomeTemplate, ConfigBuilder<TerraBiome>> {
import java.util.Map;
public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
private final ConfigPack pack; private final ConfigPack pack;
public BiomeFactory(ConfigPack pack) { public BiomeFactory(ConfigPack pack) {
@ -20,32 +15,7 @@ public class BiomeFactory implements TerraFactory<BiomeTemplate, TerraBiome> {
} }
@Override @Override
public UserDefinedBiome build(BiomeTemplate template, TerraPlugin main) { public BiomeBuilder build(BiomeTemplate template, TerraPlugin main) {
GeneratorBuilder generatorBuilder = new GeneratorBuilder(); return new BiomeBuilder(template, pack);
generatorBuilder.setElevationEquation(template.getElevationEquation());
generatorBuilder.setNoiseEquation(template.getNoiseEquation());
generatorBuilder.setCarvingEquation(template.getCarvingEquation());
generatorBuilder.setNoiseBuilderMap(pack.getTemplate().getNoiseBuilderMap());
Map<String, FunctionTemplate> functions = new LinkedHashMap<>(pack.getTemplate().getFunctions()); // linked map to preserve order.
functions.putAll(template.getFunctions());
generatorBuilder.setFunctionTemplateMap(functions);
generatorBuilder.setPalettes(template.getPalette());
generatorBuilder.setSlantPalettes(template.getSlantPalette());
Scope vars = new Scope().withParent(pack.getVarScope());
template.getVariables().forEach(vars::create);
generatorBuilder.setVarScope(vars);
generatorBuilder.setInterpolateElevation(template.interpolateElevation());
generatorBuilder.setElevationWeight(template.getElevationWeight());
generatorBuilder.setBiomeNoise(template.getBiomeNoise());
generatorBuilder.setBlendDistance(template.getBlendDistance());
generatorBuilder.setBlendStep(template.getBlendStep());
generatorBuilder.setBlendWeight(template.getBlendWeight());
return new UserDefinedBiome(template.getVanilla(), generatorBuilder, template);
} }
} }

View File

@ -11,7 +11,7 @@ import com.dfsek.terra.config.templates.CarverTemplate;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class CarverFactory implements TerraFactory<CarverTemplate, UserDefinedCarver> { public class CarverFactory implements ConfigFactory<CarverTemplate, UserDefinedCarver> {
private final ConfigPack pack; private final ConfigPack pack;
public CarverFactory(ConfigPack pack) { public CarverFactory(ConfigPack pack) {

View File

@ -4,6 +4,6 @@ import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
public interface TerraFactory<C extends ConfigTemplate, O> { public interface ConfigFactory<C extends ConfigTemplate, O> {
O build(C config, TerraPlugin main) throws LoadException; O build(C config, TerraPlugin main) throws LoadException;
} }

View File

@ -10,7 +10,7 @@ import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.config.templates.FloraTemplate; import com.dfsek.terra.config.templates.FloraTemplate;
import com.dfsek.terra.world.population.items.flora.TerraFlora; import com.dfsek.terra.world.population.items.flora.TerraFlora;
public class FloraFactory implements TerraFactory<FloraTemplate, Flora> { public class FloraFactory implements ConfigFactory<FloraTemplate, Flora> {
@Override @Override
public TerraFlora build(FloraTemplate config, TerraPlugin main) { public TerraFlora build(FloraTemplate config, TerraPlugin main) {
Palette<BlockData> palette = new NoisePalette<>(new WhiteNoiseSampler(2403), false); Palette<BlockData> palette = new NoisePalette<>(new WhiteNoiseSampler(2403), false);

View File

@ -7,7 +7,7 @@ import com.dfsek.terra.world.population.items.ores.DeformedSphereOre;
import com.dfsek.terra.world.population.items.ores.Ore; import com.dfsek.terra.world.population.items.ores.Ore;
import com.dfsek.terra.world.population.items.ores.VanillaOre; import com.dfsek.terra.world.population.items.ores.VanillaOre;
public class OreFactory implements TerraFactory<OreTemplate, Ore> { public class OreFactory implements ConfigFactory<OreTemplate, Ore> {
@Override @Override
public Ore build(OreTemplate config, TerraPlugin main) { public Ore build(OreTemplate config, TerraPlugin main) {
BlockData m = config.getMaterial(); BlockData m = config.getMaterial();

View File

@ -7,7 +7,7 @@ import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder; import com.dfsek.terra.api.world.palette.holder.PaletteLayerHolder;
import com.dfsek.terra.config.templates.PaletteTemplate; import com.dfsek.terra.config.templates.PaletteTemplate;
public class PaletteFactory implements TerraFactory<PaletteTemplate, Palette<BlockData>> { public class PaletteFactory implements ConfigFactory<PaletteTemplate, Palette<BlockData>> {
@Override @Override
public Palette<BlockData> build(PaletteTemplate config, TerraPlugin main) { public Palette<BlockData> build(PaletteTemplate config, TerraPlugin main) {
NoisePalette<BlockData> palette = new NoisePalette<>(config.getNoise().apply(2403L), config.getNoise().getDimensions() == 2); NoisePalette<BlockData> palette = new NoisePalette<>(config.getNoise().apply(2403L), config.getNoise().getDimensions() == 2);

View File

@ -4,7 +4,7 @@ import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.config.templates.StructureTemplate; import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.world.population.items.TerraStructure; import com.dfsek.terra.world.population.items.TerraStructure;
public class StructureFactory implements TerraFactory<StructureTemplate, TerraStructure> { public class StructureFactory implements ConfigFactory<StructureTemplate, TerraStructure> {
@Override @Override
public TerraStructure build(StructureTemplate config, TerraPlugin main) { public TerraStructure build(StructureTemplate config, TerraPlugin main) {
return new TerraStructure(config.getStructures(), config.getY(), config.getSpawn(), config); return new TerraStructure(config.getStructures(), config.getY(), config.getSpawn(), config);

View File

@ -5,7 +5,7 @@ import com.dfsek.terra.api.world.tree.Tree;
import com.dfsek.terra.config.templates.TreeTemplate; import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.world.population.items.tree.TerraTree; import com.dfsek.terra.world.population.items.tree.TerraTree;
public class TreeFactory implements TerraFactory<TreeTemplate, Tree> { public class TreeFactory implements ConfigFactory<TreeTemplate, Tree> {
@Override @Override
public Tree build(TreeTemplate config, TerraPlugin main) { public Tree build(TreeTemplate config, TerraPlugin main) {
return new TerraTree(config.getSpawnable(), config.getyOffset(), config.getStructures()); return new TerraTree(config.getSpawnable(), config.getyOffset(), config.getStructures());

View File

@ -5,12 +5,14 @@ import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate; import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler; import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider; import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.registry.config.BiomeRegistry; import com.dfsek.terra.registry.config.BiomeRegistry;
public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider.BiomeProviderBuilder>, BiomeProvider.BiomeProviderBuilder { public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvider.BiomeProviderBuilder>, BiomeProvider.BiomeProviderBuilder {
protected final BiomeRegistry registry; protected final Registry<TerraBiome> registry;
@Value("resolution") @Value("resolution")
@Default @Default
protected int resolution = 1; protected int resolution = 1;
@ -33,7 +35,7 @@ public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvi
@Value("type") @Value("type")
BiomeProvider.Type type; BiomeProvider.Type type;
protected BiomeProviderTemplate(BiomeRegistry registry) { protected BiomeProviderTemplate(Registry<TerraBiome> registry) {
this.registry = registry; this.registry = registry;
} }

View File

@ -1,6 +1,8 @@
package com.dfsek.terra.config.loaders.config.biome.templates.source; package com.dfsek.terra.config.loaders.config.biome.templates.source;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider; import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.api.world.biome.provider.ImageBiomeProvider; import com.dfsek.terra.api.world.biome.provider.ImageBiomeProvider;
import com.dfsek.terra.registry.config.BiomeRegistry; import com.dfsek.terra.registry.config.BiomeRegistry;
@ -14,7 +16,7 @@ public class ImageProviderTemplate extends BiomeProviderTemplate {
@Value("image.align") @Value("image.align")
private ImageBiomeProvider.Align align; private ImageBiomeProvider.Align align;
public ImageProviderTemplate(BiomeRegistry registry) { public ImageProviderTemplate(Registry<TerraBiome> registry) {
super(registry); super(registry);
} }

View File

@ -23,13 +23,15 @@ import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.tree.Tree; import com.dfsek.terra.api.world.tree.Tree;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.builder.ConfigBuilder;
import com.dfsek.terra.config.dummy.DummyWorld;
import com.dfsek.terra.config.factories.BiomeFactory; import com.dfsek.terra.config.factories.BiomeFactory;
import com.dfsek.terra.config.factories.CarverFactory; import com.dfsek.terra.config.factories.CarverFactory;
import com.dfsek.terra.config.factories.FloraFactory; import com.dfsek.terra.config.factories.FloraFactory;
import com.dfsek.terra.config.factories.OreFactory; import com.dfsek.terra.config.factories.OreFactory;
import com.dfsek.terra.config.factories.PaletteFactory; import com.dfsek.terra.config.factories.PaletteFactory;
import com.dfsek.terra.config.factories.StructureFactory; import com.dfsek.terra.config.factories.StructureFactory;
import com.dfsek.terra.config.factories.TerraFactory; import com.dfsek.terra.config.factories.ConfigFactory;
import com.dfsek.terra.config.factories.TreeFactory; import com.dfsek.terra.config.factories.TreeFactory;
import com.dfsek.terra.config.fileloaders.FolderLoader; import com.dfsek.terra.config.fileloaders.FolderLoader;
import com.dfsek.terra.config.fileloaders.Loader; import com.dfsek.terra.config.fileloaders.Loader;
@ -60,7 +62,7 @@ import com.dfsek.terra.registry.config.PaletteRegistry;
import com.dfsek.terra.registry.config.ScriptRegistry; import com.dfsek.terra.registry.config.ScriptRegistry;
import com.dfsek.terra.registry.config.StructureRegistry; import com.dfsek.terra.registry.config.StructureRegistry;
import com.dfsek.terra.registry.config.TreeRegistry; import com.dfsek.terra.registry.config.TreeRegistry;
import com.dfsek.terra.world.generation.math.SamplerCache; import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.population.items.TerraStructure; import com.dfsek.terra.world.population.items.TerraStructure;
import com.dfsek.terra.world.population.items.ores.Ore; import com.dfsek.terra.world.population.items.ores.Ore;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -106,8 +108,6 @@ public class ConfigPack implements LoaderRegistrar {
private final ConfigLoader selfLoader = new ConfigLoader(); private final ConfigLoader selfLoader = new ConfigLoader();
private final Scope varScope = new Scope(); private final Scope varScope = new Scope();
private final SamplerCache samplerCache;
private final TerraPlugin main; private final TerraPlugin main;
private final Loader loader; private final Loader loader;
@ -119,7 +119,6 @@ public class ConfigPack implements LoaderRegistrar {
this.loader = new FolderLoader(folder.toPath()); this.loader = new FolderLoader(folder.toPath());
this.main = main; this.main = main;
long l = System.nanoTime(); long l = System.nanoTime();
this.samplerCache = new SamplerCache(main);
floraRegistry = new FloraRegistry(main); floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main); paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry(main); treeRegistry = new TreeRegistry(main);
@ -148,6 +147,7 @@ public class ConfigPack implements LoaderRegistrar {
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 TerraWorld(new DummyWorld(), this, main)); // Build now to catch any errors immediately.
} }
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException { public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
@ -155,7 +155,6 @@ public class ConfigPack implements LoaderRegistrar {
this.loader = new ZIPLoader(file); this.loader = new ZIPLoader(file);
this.main = main; this.main = main;
long l = System.nanoTime(); long l = System.nanoTime();
this.samplerCache = new SamplerCache(main);
floraRegistry = new FloraRegistry(main); floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main); paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry(main); treeRegistry = new TreeRegistry(main);
@ -192,9 +191,11 @@ public class ConfigPack implements LoaderRegistrar {
main.logger().severe("Failed to load config pack from ZIP archive \"" + file.getName() + "\""); main.logger().severe("Failed to load config pack from ZIP archive \"" + file.getName() + "\"");
throw e; throw e;
} }
toWorldConfig(new TerraWorld(new DummyWorld(), this, main)); // Build now to catch any errors immediately.
} }
public static <C extends AbstractableTemplate, O> void buildAll(TerraFactory<C, O> factory, OpenRegistry<O> registry, List<C> configTemplates, TerraPlugin main) throws LoadException { public static <C extends AbstractableTemplate, O> void buildAll(ConfigFactory<C, O> factory, OpenRegistry<O> registry, List<C> configTemplates, TerraPlugin main) throws LoadException {
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main)); for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main));
} }
@ -207,10 +208,10 @@ public class ConfigPack implements LoaderRegistrar {
loader.open("structures/data", ".tesf").thenEntries(entries -> { loader.open("structures/data", ".tesf").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) { for(Map.Entry<String, InputStream> entry : entries) {
try { try(InputStream stream = entry.getValue()) {
StructureScript structureScript = new StructureScript(entry.getValue(), main, scriptRegistry, lootRegistry, samplerCache, functionRegistry); StructureScript structureScript = new StructureScript(stream, main, scriptRegistry, lootRegistry, functionRegistry);
scriptRegistry.add(structureScript.getId(), structureScript); scriptRegistry.add(structureScript.getId(), structureScript);
} catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException e) { } catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException | IOException e) {
throw new LoadException("Unable to load script \"" + entry.getKey() + "\"", e); throw new LoadException("Unable to load script \"" + entry.getKey() + "\"", e);
} }
} }
@ -237,14 +238,6 @@ public class ConfigPack implements LoaderRegistrar {
main.logger().info("Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " + (System.nanoTime() - start) / 1000000D + "ms."); main.logger().info("Loaded config pack \"" + template.getID() + "\" v" + template.getVersion() + " by " + template.getAuthor() + " in " + (System.nanoTime() - start) / 1000000D + "ms.");
} }
public TerraBiome getBiome(String id) {
return biomeRegistry.get(id);
}
public List<String> getBiomeIDs() {
return biomeRegistry.entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
}
public TerraStructure getStructure(String id) { public TerraStructure getStructure(String id) {
return structureRegistry.get(id); return structureRegistry.get(id);
} }
@ -285,10 +278,6 @@ public class ConfigPack implements LoaderRegistrar {
.registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry)); .registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry));
} }
public SamplerCache getSamplerCache() {
return samplerCache;
}
public Set<UserDefinedCarver> getCarvers() { public Set<UserDefinedCarver> getCarvers() {
return carverRegistry.entries(); return carverRegistry.entries();
} }
@ -301,7 +290,7 @@ public class ConfigPack implements LoaderRegistrar {
return new CheckedRegistry<>(scriptRegistry); return new CheckedRegistry<>(scriptRegistry);
} }
public CheckedRegistry<TerraBiome> getBiomeRegistry() { public CheckedRegistry<ConfigBuilder<TerraBiome>> getBiomeRegistry() {
return new CheckedRegistry<>(biomeRegistry); return new CheckedRegistry<>(biomeRegistry);
} }
@ -340,4 +329,8 @@ public class ConfigPack implements LoaderRegistrar {
public CheckedRegistry<TerraStructure> getStructureRegistry() { public CheckedRegistry<TerraStructure> getStructureRegistry() {
return new CheckedRegistry<>(structureRegistry); return new CheckedRegistry<>(structureRegistry);
} }
public WorldConfig toWorldConfig(TerraWorld world){
return new WorldConfig(world, this, main);
}
} }

View File

@ -0,0 +1,124 @@
package com.dfsek.terra.config.pack;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.tree.Tree;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.registry.OpenRegistry;
import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.generation.math.SamplerCache;
import com.dfsek.terra.world.population.items.TerraStructure;
import com.dfsek.terra.world.population.items.ores.Ore;
import java.util.Set;
import java.util.function.Supplier;
public class WorldConfig {
private final LockedRegistry<StructureScript> scriptRegistry;
private final LockedRegistry<TerraBiome> biomeRegistry;
private final SamplerCache samplerCache;
private final LockedRegistry<UserDefinedCarver> carverRegistry;
private final LockedRegistry<Tree> treeRegistry;
private final LockedRegistry<Flora> floraRegistry;
private final LockedRegistry<LootTable> lootRegistry;
private final LockedRegistry<Ore> oreRegistry;
private final LockedRegistry<Palette<BlockData>> paletteRegistry;
private final LockedRegistry<TerraStructure> structureRegistry;
private final BiomeProvider provider;
private final TerraWorld world;
private final ConfigPack pack;
public WorldConfig(TerraWorld world, ConfigPack pack, TerraPlugin main) {
this.world = world;
this.pack = pack;
this.samplerCache = new SamplerCache(main, world);
this.scriptRegistry = new LockedRegistry<>(pack.getScriptRegistry());
OpenRegistry<TerraBiome> biomeOpenRegistry = new OpenRegistry<>();
pack.getBiomeRegistry().forEach((id, biome) -> biomeOpenRegistry.add(id, biome.build(world, main)));
this.biomeRegistry = new LockedRegistry<>(biomeOpenRegistry);
this.carverRegistry = new LockedRegistry<>(pack.getCarverRegistry());
this.treeRegistry = new LockedRegistry<>(pack.getTreeRegistry());
this.floraRegistry = new LockedRegistry<>(pack.getFloraRegistry());
this.lootRegistry = new LockedRegistry<>(pack.getLootRegistry());
this.oreRegistry = new LockedRegistry<>(pack.getOreRegistry());
this.paletteRegistry = new LockedRegistry<>(pack.getPaletteRegistry());
this.structureRegistry = new LockedRegistry<>(pack.getStructureRegistry());
this.provider = pack.getBiomeProviderBuilder().build(world.getWorld().getSeed());
}
public TerraWorld getWorld() {
return world;
}
public SamplerCache getSamplerCache() {
return samplerCache;
}
public Set<UserDefinedCarver> getCarvers() {
return carverRegistry.entries();
}
public LockedRegistry<StructureScript> getScriptRegistry() {
return scriptRegistry;
}
public LockedRegistry<TerraBiome> getBiomeRegistry() {
return biomeRegistry;
}
public LockedRegistry<Tree> getTreeRegistry() {
return treeRegistry;
}
public LockedRegistry<UserDefinedCarver> getCarverRegistry() {
return carverRegistry;
}
public LockedRegistry<Flora> getFloraRegistry() {
return floraRegistry;
}
public LockedRegistry<LootTable> getLootRegistry() {
return lootRegistry;
}
public LockedRegistry<Ore> getOreRegistry() {
return oreRegistry;
}
public LockedRegistry<Palette<BlockData>> getPaletteRegistry() {
return paletteRegistry;
}
public LockedRegistry<TerraStructure> getStructureRegistry() {
return structureRegistry;
}
public BiomeProvider getProvider() {
return provider;
}
public Set<TerraStructure> getStructures() {
return structureRegistry.entries();
}
public ConfigPackTemplate getTemplate() {
return pack.getTemplate();
}
}

View File

@ -31,6 +31,7 @@ import com.dfsek.terra.world.population.items.ores.OreHolder;
import com.dfsek.terra.world.population.items.tree.TreeLayer; import com.dfsek.terra.world.population.items.tree.TreeLayer;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -182,7 +183,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Value("tags") @Value("tags")
@Default @Default
@Abstractable @Abstractable
private Set<String> tags; private Set<String> tags = new HashSet<>();
@Value("carving") @Value("carving")
@Abstractable @Abstractable

View File

@ -17,7 +17,7 @@ import java.util.function.Consumer;
* Registry implementation with read/write access. For internal use only. * Registry implementation with read/write access. For internal use only.
* @param <T> * @param <T>
*/ */
public abstract class OpenRegistry<T> implements Registry<T> { public class OpenRegistry<T> implements Registry<T> {
private final Map<String, T> objects = new HashMap<>(); private final Map<String, T> objects = new HashMap<>();
@Override @Override

View File

@ -3,15 +3,16 @@ package com.dfsek.terra.registry.config;
import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.config.builder.ConfigBuilder;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
import java.lang.reflect.Type; import java.lang.reflect.Type;
public class BiomeRegistry extends OpenRegistry<TerraBiome> { public class BiomeRegistry extends OpenRegistry<ConfigBuilder<TerraBiome>> {
@Override @Override
public TerraBiome load(Type type, Object o, ConfigLoader configLoader) throws LoadException { public ConfigBuilder<TerraBiome> load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
if(o.equals("SELF")) return null; if(o.equals("SELF")) return null;
TerraBiome biome = get((String) o); ConfigBuilder<TerraBiome> biome = get((String) o);
if(biome == null) if(biome == null)
throw new LoadException("No such " + type.getTypeName() + " matching \"" + o + "\" was found in this registry."); throw new LoadException("No such " + type.getTypeName() + " matching \"" + o + "\" was found in this registry.");
return biome; return biome;

View File

@ -12,13 +12,14 @@ import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator; import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.profiler.WorldProfiler; import com.dfsek.terra.profiler.WorldProfiler;
import com.dfsek.terra.world.generation.math.samplers.Sampler; import com.dfsek.terra.world.generation.math.samplers.Sampler;
import net.jafama.FastMath; import net.jafama.FastMath;
public class TerraWorld { public class TerraWorld {
private final BiomeProvider provider; private final BiomeProvider provider;
private final ConfigPack config; private final WorldConfig config;
private final boolean safe; private final boolean safe;
private final WorldProfiler profiler; private final WorldProfiler profiler;
private final World world; private final World world;
@ -27,10 +28,9 @@ public class TerraWorld {
public TerraWorld(World w, ConfigPack c, TerraPlugin main) { public TerraWorld(World w, ConfigPack c, TerraPlugin main) {
if(!isTerraWorld(w)) throw new IllegalArgumentException("World " + w + " is not a Terra World!"); if(!isTerraWorld(w)) throw new IllegalArgumentException("World " + w + " is not a Terra World!");
c.getBiomeRegistry().forEach(biome -> biome.getGenerator(w)); // Load all gens to cache config = c.toWorldConfig(this);
config = c;
profiler = new WorldProfiler(w); profiler = new WorldProfiler(w);
this.provider = config.getBiomeProviderBuilder().build(w.getSeed()); this.provider = config.getProvider();
this.world = w; this.world = w;
air = main.getWorldHandle().createBlockData("minecraft:air"); air = main.getWorldHandle().createBlockData("minecraft:air");
main.getEventManager().callEvent(new TerraWorldLoadEvent(this)); main.getEventManager().callEvent(new TerraWorldLoadEvent(this));
@ -53,7 +53,7 @@ public class TerraWorld {
return provider; return provider;
} }
public ConfigPack getConfig() { public WorldConfig getConfig() {
return config; return config;
} }
@ -76,7 +76,7 @@ public class TerraWorld {
public BlockData getUngeneratedBlock(int x, int y, int z) { public BlockData getUngeneratedBlock(int x, int y, int z) {
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(x, z); UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(x, z);
Palette<BlockData> palette = biome.getGenerator(world).getPalette(y); Palette<BlockData> palette = biome.getGenerator(world).getPalette(y);
Sampler sampler = config.getSamplerCache().get(world, x, z); Sampler sampler = config.getSamplerCache().get(x, z);
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);

View File

@ -86,7 +86,7 @@ public class DefaultChunkGenerator2D implements TerraChunkGenerator {
int xOrig = (chunkX << 4); int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4); int zOrig = (chunkZ << 4);
Sampler sampler = cache.getChunk(world, chunkX, chunkZ); Sampler sampler = cache.getChunk(chunkX, chunkZ);
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++) {

View File

@ -99,7 +99,7 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
int xOrig = (chunkX << 4); int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4); int zOrig = (chunkZ << 4);
Sampler sampler = cache.getChunk(world, chunkX, chunkZ); Sampler sampler = cache.getChunk(chunkX, chunkZ);
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++) {

View File

@ -16,45 +16,18 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class SamplerCache { public class SamplerCache {
private final Map<Long, Container> containerMap;
private final TerraPlugin main;
public SamplerCache(TerraPlugin main) {
containerMap = Collections.synchronizedMap(new HashMap<>());
this.main = main;
}
public Sampler get(World world, int x, int z) {
synchronized(containerMap) {
return containerMap.computeIfAbsent(world.getSeed(), seed -> new Container(world)).get(x, z);
}
}
public Sampler getChunk(World world, int chunkX, int chunkZ) {
synchronized(containerMap) {
return containerMap.computeIfAbsent(world.getSeed(), seed -> new Container(world)).getChunk(chunkX, chunkZ);
}
}
public void clear() {
containerMap.clear();
}
private final class Container {
private final TerraWorld terraWorld;
private final LoadingCache<Long, Sampler> cache; private final LoadingCache<Long, Sampler> cache;
private Container(World world) { public SamplerCache(TerraPlugin main, TerraWorld world) {
cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache()) cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getSamplerCache())
.build(new CacheLoader<Long, Sampler>() { .build(new CacheLoader<Long, Sampler>() {
@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 terraWorld.getGenerator().createSampler(cx, cz, terraWorld.getBiomeProvider(), world, terraWorld.getConfig().getTemplate().getElevationBlend()); return world.getGenerator().createSampler(cx, cz, world.getBiomeProvider(), world.getWorld(), world.getConfig().getTemplate().getElevationBlend());
} }
}); });
terraWorld = main.getWorld(world);
} }
public Sampler get(int x, int z) { public Sampler get(int x, int z) {
@ -68,4 +41,3 @@ public class SamplerCache {
return cache.getUnchecked(key); return cache.getUnchecked(key);
} }
} }
}

View File

@ -12,6 +12,7 @@ import com.dfsek.terra.api.util.world.PopulationUtil;
import com.dfsek.terra.api.world.generation.TerraBlockPopulator; import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.config.templates.CarverTemplate; import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.profiler.ProfileFuture; import com.dfsek.terra.profiler.ProfileFuture;
import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.TerraWorld;
@ -40,7 +41,7 @@ public class CavePopulator implements TerraBlockPopulator {
try(ProfileFuture ignored = tw.getProfiler().measure("CaveTime")) { try(ProfileFuture ignored = tw.getProfiler().measure("CaveTime")) {
Random random = PopulationUtil.getRandom(chunk); Random random = PopulationUtil.getRandom(chunk);
if(!tw.isSafe()) return; if(!tw.isSafe()) return;
ConfigPack config = tw.getConfig(); WorldConfig config = tw.getConfig();
for(UserDefinedCarver c : config.getCarvers()) { for(UserDefinedCarver c : config.getCarvers()) {
CarverTemplate template = c.getConfig(); CarverTemplate template = c.getConfig();

View File

@ -11,6 +11,7 @@ import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider; import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.api.world.generation.TerraBlockPopulator; import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
import com.dfsek.terra.config.pack.ConfigPack; import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.profiler.ProfileFuture; import com.dfsek.terra.profiler.ProfileFuture;
import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.population.items.TerraStructure; import com.dfsek.terra.world.population.items.TerraStructure;
@ -35,7 +36,7 @@ public class StructurePopulator implements TerraBlockPopulator {
int cz = (chunk.getZ() << 4); int cz = (chunk.getZ() << 4);
if(!tw.isSafe()) return; if(!tw.isSafe()) return;
BiomeProvider provider = tw.getBiomeProvider(); BiomeProvider provider = tw.getBiomeProvider();
ConfigPack config = tw.getConfig(); WorldConfig config = tw.getConfig();
for(TerraStructure conf : config.getStructures()) { for(TerraStructure conf : config.getStructures()) {
Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world); Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world);