Merge pull request #118 from PolyhedralDev/dev/directories

Remove hard-coded registries, allow addons to register custom config types, remove strict directory requirements
This commit is contained in:
dfsek
2021-04-11 21:26:36 -07:00
committed by GitHub
62 changed files with 533 additions and 946 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
import com.dfsek.terra.getGitHash import com.dfsek.terra.getGitHash
val versionObj = Version("5", "1", "2", true) val versionObj = Version("6", "0", "0", true)
allprojects { allprojects {
version = versionObj version = versionObj
@@ -18,9 +18,7 @@ fun Project.configureDependencies() {
dependencies { dependencies {
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0") "testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
"testImplementation"("org.yaml:snakeyaml:1.27") "testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
"testImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
"compileOnly"("org.jetbrains:annotations:20.1.0") "compileOnly"("org.jetbrains:annotations:20.1.0")
} }
} }
@@ -62,8 +62,14 @@ fun Project.configureDistribution() {
archiveClassifier.set("shaded") archiveClassifier.set("shaded")
setVersion(project.version) setVersion(project.version)
relocate("org.apache.commons", "com.dfsek.terra.lib.commons") relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
relocate("parsii", "com.dfsek.terra.lib.parsii")
relocate("net.jafama", "com.dfsek.terra.lib.jafama") relocate("net.jafama", "com.dfsek.terra.lib.jafama")
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
relocate("com.google.errorprone", "com.dfsek.terra.lib.google.errorprone")
relocate("com.google.j2objc", "com.dfsek.terra.lib.google.j2objc")
relocate("org.checkerframework", "com.dfsek.terra.lib.checkerframework")
relocate("org.javax.annotation", "com.dfsek.terra.lib.javax.annotation")
relocate("org.json", "com.dfsek.terra.lib.json")
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
minimize() minimize()
} }
convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name convention.getPlugin<BasePluginConvention>().archivesBaseName = project.name
+3 -2
View File
@@ -14,13 +14,14 @@ dependencies {
"shadedApi"("commons-io:commons-io:2.4") "shadedApi"("commons-io:commons-io:2.4")
"shadedApi"("com.dfsek:Paralithic:0.3.2") "shadedApi"("com.dfsek:Paralithic:0.3.2")
"shadedApi"("com.dfsek:Tectonic:1.2.3") "shadedApi"("com.dfsek:Tectonic:1.3.1")
"shadedApi"("net.jafama:jafama:2.3.2") "shadedApi"("net.jafama:jafama:2.3.2")
"shadedApi"("org.yaml:snakeyaml:1.27") "shadedApi"("org.yaml:snakeyaml:1.27")
"shadedApi"("org.ow2.asm:asm:9.0") "shadedApi"("org.ow2.asm:asm:9.0")
"shadedApi"("commons-io:commons-io:2.6") "shadedApi"("commons-io:commons-io:2.6")
"compileOnly"("com.googlecode.json-simple:json-simple:1.1") "shadedApi"("com.googlecode.json-simple:json-simple:1.1.1")
"shadedApi"("org.yaml:snakeyaml:1.27")
"compileOnly"("com.google.guava:guava:30.0-jre") "compileOnly"("com.google.guava:guava:30.0-jre")
@@ -6,6 +6,7 @@ import com.dfsek.terra.registry.OpenRegistry;
import com.dfsek.terra.registry.exception.DuplicateEntryException; import com.dfsek.terra.registry.exception.DuplicateEntryException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -68,7 +69,7 @@ public class CheckedRegistry<T> implements Registry<T> {
} }
@Override @Override
public Set<T> entries() { public Collection<T> entries() {
return registry.entries(); return registry.entries();
} }
@@ -4,6 +4,7 @@ import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.ConfigLoader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -41,7 +42,7 @@ public class LockedRegistry<T> implements Registry<T> {
} }
@Override @Override
public Set<T> entries() { public Collection<T> entries() {
return registry.entries(); return registry.entries();
} }
@@ -2,6 +2,7 @@ package com.dfsek.terra.api.registry;
import com.dfsek.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import java.util.Collection;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -42,7 +43,7 @@ public interface Registry<T> extends TypeLoader<T> {
* *
* @return Set containing all entries. * @return Set containing all entries.
*/ */
Set<T> entries(); Collection<T> entries();
/** /**
* Get all the keys in this registry. * Get all the keys in this registry.
@@ -3,10 +3,13 @@ package com.dfsek.terra.api.structures.script;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.math.vector.Location; import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.world.Chunk; import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.Parser; import com.dfsek.terra.api.structures.parser.Parser;
import com.dfsek.terra.api.structures.parser.exceptions.ParseException; import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
import com.dfsek.terra.api.structures.parser.lang.Block; import com.dfsek.terra.api.structures.parser.lang.Block;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.builders.BinaryNumberFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.BinaryNumberFunctionBuilder;
import com.dfsek.terra.api.structures.script.builders.BiomeFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.BiomeFunctionBuilder;
import com.dfsek.terra.api.structures.script.builders.BlockFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.BlockFunctionBuilder;
@@ -29,9 +32,6 @@ import com.dfsek.terra.api.structures.structure.Rotation;
import com.dfsek.terra.api.structures.structure.buffer.Buffer; import com.dfsek.terra.api.structures.structure.buffer.Buffer;
import com.dfsek.terra.api.structures.structure.buffer.DirectBuffer; import com.dfsek.terra.api.structures.structure.buffer.DirectBuffer;
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer; import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
import com.dfsek.terra.registry.config.FunctionRegistry;
import com.dfsek.terra.registry.config.LootRegistry;
import com.dfsek.terra.registry.config.ScriptRegistry;
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 +49,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, FunctionRegistry functionRegistry) throws ParseException { public StructureScript(InputStream inputStream, TerraPlugin main, Registry<StructureScript> registry, Registry<LootTable> lootRegistry, Registry<FunctionBuilder<?>> functionRegistry) throws ParseException {
Parser parser; Parser parser;
try { try {
parser = new Parser(IOUtils.toString(inputStream)); parser = new Parser(IOUtils.toString(inputStream));
@@ -1,21 +1,22 @@
package com.dfsek.terra.api.structures.script.builders; package com.dfsek.terra.api.structures.script.builders;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.StructureScript; import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.script.functions.LootFunction; import com.dfsek.terra.api.structures.script.functions.LootFunction;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.registry.config.LootRegistry;
import java.util.List; import java.util.List;
public class LootFunctionBuilder implements FunctionBuilder<LootFunction> { public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
private final TerraPlugin main; private final TerraPlugin main;
private final LootRegistry registry; private final Registry<LootTable> registry;
private final StructureScript script; private final StructureScript script;
public LootFunctionBuilder(TerraPlugin main, LootRegistry registry, StructureScript script) { public LootFunctionBuilder(TerraPlugin main, Registry<LootTable> registry, StructureScript script) {
this.main = main; this.main = main;
this.registry = registry; this.registry = registry;
this.script = script; this.script = script;
@@ -1,21 +1,22 @@
package com.dfsek.terra.api.structures.script.builders; package com.dfsek.terra.api.structures.script.builders;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structures.parser.exceptions.ParseException; import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.script.functions.StructureFunction; import com.dfsek.terra.api.structures.script.functions.StructureFunction;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.registry.config.ScriptRegistry;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class StructureFunctionBuilder implements FunctionBuilder<StructureFunction> { public class StructureFunctionBuilder implements FunctionBuilder<StructureFunction> {
private final ScriptRegistry registry; private final Registry<StructureScript> registry;
private final TerraPlugin main; private final TerraPlugin main;
public StructureFunctionBuilder(ScriptRegistry registry, TerraPlugin main) { public StructureFunctionBuilder(Registry<StructureScript> registry, TerraPlugin main) {
this.registry = registry; this.registry = registry;
this.main = main; this.main = main;
} }
@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.script.functions;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.math.vector.Vector2; import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.math.vector.Vector3; import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structures.loot.LootTable; import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
@@ -13,20 +14,19 @@ import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication; import com.dfsek.terra.api.structures.structure.buffer.items.BufferedLootApplication;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.registry.config.LootRegistry;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.Map; import java.util.Map;
public class LootFunction implements Function<Void> { public class LootFunction implements Function<Void> {
private final LootRegistry registry; private final Registry<LootTable> registry;
private final Returnable<String> data; private final Returnable<String> data;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
private final TerraPlugin main; private final TerraPlugin main;
private final StructureScript script; private final StructureScript script;
public LootFunction(LootRegistry registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position, StructureScript script) { public LootFunction(Registry<LootTable> registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position, StructureScript script) {
this.registry = registry; this.registry = registry;
this.position = position; this.position = position;
this.data = data; this.data = data;
@@ -3,6 +3,7 @@ package com.dfsek.terra.api.structures.script.functions;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.math.vector.Vector2; import com.dfsek.terra.api.math.vector.Vector2;
import com.dfsek.terra.api.math.vector.Vector3; import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.api.structures.parser.lang.Returnable; import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.Function; import com.dfsek.terra.api.structures.parser.lang.functions.Function;
@@ -13,21 +14,20 @@ import com.dfsek.terra.api.structures.structure.Rotation;
import com.dfsek.terra.api.structures.structure.RotationUtil; import com.dfsek.terra.api.structures.structure.RotationUtil;
import com.dfsek.terra.api.structures.structure.buffer.IntermediateBuffer; import com.dfsek.terra.api.structures.structure.buffer.IntermediateBuffer;
import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.registry.config.ScriptRegistry;
import net.jafama.FastMath; import net.jafama.FastMath;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class StructureFunction implements Function<Boolean> { public class StructureFunction implements Function<Boolean> {
private final ScriptRegistry registry; private final Registry<StructureScript> registry;
private final Returnable<String> id; private final Returnable<String> id;
private final Returnable<Number> x, y, z; private final Returnable<Number> x, y, z;
private final Position position; private final Position position;
private final TerraPlugin main; private final TerraPlugin main;
private final List<Returnable<String>> rotations; private final List<Returnable<String>> rotations;
public StructureFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> id, List<Returnable<String>> rotations, ScriptRegistry registry, Position position, TerraPlugin main) { public StructureFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> id, List<Returnable<String>> rotations, Registry<StructureScript> registry, Position position, TerraPlugin main) {
this.registry = registry; this.registry = registry;
this.id = id; this.id = id;
this.position = position; this.position = position;
@@ -15,6 +15,7 @@ public class Tokenizer {
private final Lookahead reader; private final Lookahead reader;
private final Stack<Token> brackets = new Stack<>(); private final Stack<Token> brackets = new Stack<>();
private Token current; private Token current;
private Token last;
public Tokenizer(String data) throws ParseException { public Tokenizer(String data) throws ParseException {
reader = new Lookahead(new StringReader(data + '\0')); reader = new Lookahead(new StringReader(data + '\0'));
@@ -28,7 +29,7 @@ public class Tokenizer {
* @throws ParseException If token does not exist * @throws ParseException If token does not exist
*/ */
public Token get() throws ParseException { public Token get() throws ParseException {
if(!hasNext()) throw new ParseException("Unexpected end of input", current.getPosition()); if(!hasNext()) throw new ParseException("Unexpected end of input", last.getPosition());
return current; return current;
} }
@@ -39,7 +40,7 @@ public class Tokenizer {
* @throws ParseException If token does not exist * @throws ParseException If token does not exist
*/ */
public Token consume() throws ParseException { public Token consume() throws ParseException {
if(!hasNext()) throw new ParseException("Unexpected end of input", current.getPosition()); if(!hasNext()) throw new ParseException("Unexpected end of input", last.getPosition());
Token temp = current; Token temp = current;
current = fetchCheck(); current = fetchCheck();
return temp; return temp;
@@ -57,8 +58,9 @@ public class Tokenizer {
private Token fetchCheck() throws ParseException { private Token fetchCheck() throws ParseException {
Token fetch = fetch(); Token fetch = fetch();
if(fetch != null) { if(fetch != null) {
if(fetch.getType().equals(Token.Type.BLOCK_BEGIN)) brackets.push(fetch); // Opening bracket last = fetch;
else if(fetch.getType().equals(Token.Type.BLOCK_END)) { if(fetch.getType() == Token.Type.BLOCK_BEGIN) brackets.push(fetch); // Opening bracket
else if(fetch.getType() == Token.Type.BLOCK_END) {
if(!brackets.isEmpty()) brackets.pop(); if(!brackets.isEmpty()) brackets.pop();
else throw new ParseException("Dangling opening brace", new Position(0, 0)); else throw new ParseException("Dangling opening brace", new Position(0, 0));
} }
@@ -1,10 +1,12 @@
package com.dfsek.terra.api.util.generic.pair; package com.dfsek.terra.api.util.generic.pair;
public class ImmutablePair<L, R> { public final class ImmutablePair<L, R> {
private final L left; private final L left;
private final R right; private final R right;
public ImmutablePair(L left, R right) { private static final ImmutablePair<?, ?> NULL = new ImmutablePair<>(null, null);
private ImmutablePair(L left, R right) {
this.left = left; this.left = left;
this.right = right; this.right = right;
} }
@@ -21,7 +23,12 @@ public class ImmutablePair<L, R> {
return left; return left;
} }
@SuppressWarnings("unchecked")
public static <L1, R1> ImmutablePair<L1, R1> ofNull() {
return (ImmutablePair<L1, R1>) NULL;
}
public Pair<L, R> mutable() { public Pair<L, R> mutable() {
return new Pair<>(left, right); return Pair.of(left, right);
} }
} }
@@ -4,7 +4,7 @@ public class Pair<L, R> {
private L left; private L left;
private R right; private R right;
public Pair(L left, R right) { private Pair(L left, R right) {
this.left = left; this.left = left;
this.right = right; this.right = right;
} }
@@ -30,6 +30,6 @@ public class Pair<L, R> {
} }
public ImmutablePair<L, R> immutable() { public ImmutablePair<L, R> immutable() {
return new ImmutablePair<>(left, right); return ImmutablePair.of(left, right);
} }
} }
@@ -0,0 +1,9 @@
package com.dfsek.terra.api.util.seeded;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import java.util.function.Supplier;
@FunctionalInterface
public interface NoiseProvider extends Supplier<ObjectTemplate<NoiseSeeded>> {
}
@@ -1,14 +1,13 @@
package com.dfsek.terra.api.util.world; package com.dfsek.terra.api.util.world;
import com.dfsek.terra.api.math.MathUtil; import com.dfsek.terra.api.math.MathUtil;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.generation.math.samplers.Sampler; import com.dfsek.terra.world.generation.math.samplers.Sampler;
public final class PaletteUtil { public final class PaletteUtil {
public static Palette<BlockData> getPalette(int x, int y, int z, BiomeTemplate c, Sampler sampler) { public static Palette getPalette(int x, int y, int z, BiomeTemplate c, Sampler sampler) {
PaletteHolder slant = c.getSlantPalette(); PaletteHolder slant = c.getSlantPalette();
if(slant != null && MathUtil.derivative(sampler, x, y, z) > c.getSlantThreshold()) { if(slant != null && MathUtil.derivative(sampler, x, y, z) > c.getSlantThreshold()) {
return slant.getPalette(y); return slant.getPalette(y);
@@ -1,7 +1,6 @@
package com.dfsek.terra.api.world.biome; package com.dfsek.terra.api.world.biome;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
public interface Generator { public interface Generator {
@@ -35,7 +34,7 @@ public interface Generator {
* *
* @return BlocPalette - The biome's palette. * @return BlocPalette - The biome's palette.
*/ */
Palette<BlockData> getPalette(int y); Palette getPalette(int y);
NoiseSampler getBiomeNoise(); NoiseSampler getBiomeNoise();
@@ -1,10 +1,11 @@
package com.dfsek.terra.api.world.palette; package com.dfsek.terra.api.world.palette;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData;
import java.util.List; import java.util.List;
public class NoisePalette<E> extends Palette<E> { public class NoisePalette extends Palette {
private final NoiseSampler sampler; private final NoiseSampler sampler;
private final boolean is2D; private final boolean is2D;
@@ -14,11 +15,11 @@ public class NoisePalette<E> extends Palette<E> {
} }
@Override @Override
public E get(int layer, double x, double y, double z) { public BlockData get(int layer, double x, double y, double z) {
PaletteLayer<E> paletteLayer; PaletteLayer paletteLayer;
if(layer > this.getSize()) paletteLayer = this.getLayers().get(this.getLayers().size() - 1); if(layer > this.getSize()) paletteLayer = this.getLayers().get(this.getLayers().size() - 1);
else { else {
List<PaletteLayer<E>> pl = getLayers(); List<PaletteLayer> pl = getLayers();
if(layer >= pl.size()) paletteLayer = pl.get(pl.size() - 1); if(layer >= pl.size()) paletteLayer = pl.get(pl.size() - 1);
else paletteLayer = pl.get(layer); else paletteLayer = pl.get(layer);
} }
@@ -1,6 +1,7 @@
package com.dfsek.terra.api.world.palette; package com.dfsek.terra.api.world.palette;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.util.GlueList; import com.dfsek.terra.api.util.GlueList;
import com.dfsek.terra.api.util.collections.ProbabilityCollection; import com.dfsek.terra.api.util.collections.ProbabilityCollection;
@@ -11,8 +12,8 @@ import java.util.Random;
* A class representation of a "slice" of the world. * A class representation of a "slice" of the world.
* Used to get a section of blocks, based on the depth at which they are found. * Used to get a section of blocks, based on the depth at which they are found.
*/ */
public abstract class Palette<E> { public abstract class Palette {
private final List<PaletteLayer<E>> pallet = new GlueList<>(); private final List<PaletteLayer> pallet = new GlueList<>();
/** /**
* Constructs a blank palette. * Constructs a blank palette.
@@ -21,16 +22,16 @@ public abstract class Palette<E> {
} }
public com.dfsek.terra.api.world.palette.Palette<E> add(E m, int layers, NoiseSampler sampler) { public com.dfsek.terra.api.world.palette.Palette add(BlockData m, int layers, NoiseSampler sampler) {
for(int i = 0; i < layers; i++) { for(int i = 0; i < layers; i++) {
pallet.add(new PaletteLayer<>(m, sampler)); pallet.add(new PaletteLayer(m, sampler));
} }
return this; return this;
} }
public com.dfsek.terra.api.world.palette.Palette<E> add(ProbabilityCollection<E> m, int layers, NoiseSampler sampler) { public com.dfsek.terra.api.world.palette.Palette add(ProbabilityCollection<BlockData> m, int layers, NoiseSampler sampler) {
for(int i = 0; i < layers; i++) { for(int i = 0; i < layers; i++) {
pallet.add(new PaletteLayer<>(m, sampler)); pallet.add(new PaletteLayer(m, sampler));
} }
return this; return this;
} }
@@ -41,25 +42,25 @@ public abstract class Palette<E> {
* @param layer - The layer at which to fetch the material. * @param layer - The layer at which to fetch the material.
* @return BlockData - The material fetched. * @return BlockData - The material fetched.
*/ */
public abstract E get(int layer, double x, double y, double z); public abstract BlockData get(int layer, double x, double y, double z);
public int getSize() { public int getSize() {
return pallet.size(); return pallet.size();
} }
public List<PaletteLayer<E>> getLayers() { public List<PaletteLayer> getLayers() {
return pallet; return pallet;
} }
/** /**
* Class representation of a layer of a BlockPalette. * Class representation of a layer of a BlockPalette.
*/ */
public static class PaletteLayer<E> { public static class PaletteLayer {
private final boolean col; // Is layer using a collection? private final boolean col; // Is layer using a collection?
private ProbabilityCollection<E> collection; private ProbabilityCollection<BlockData> collection;
private final NoiseSampler sampler; private final NoiseSampler sampler;
private E m; private BlockData m;
/** /**
* Constructs a PaletteLayerHolder with a ProbabilityCollection of materials and a number of layers. * Constructs a PaletteLayerHolder with a ProbabilityCollection of materials and a number of layers.
@@ -67,7 +68,7 @@ public abstract class Palette<E> {
* @param type The collection of materials to choose from. * @param type The collection of materials to choose from.
* @param sampler Noise sampler to use * @param sampler Noise sampler to use
*/ */
public PaletteLayer(ProbabilityCollection<E> type, NoiseSampler sampler) { public PaletteLayer(ProbabilityCollection<BlockData> type, NoiseSampler sampler) {
this.sampler = sampler; this.sampler = sampler;
this.col = true; this.col = true;
this.collection = type; this.collection = type;
@@ -79,7 +80,7 @@ public abstract class Palette<E> {
* @param type The material to use. * @param type The material to use.
* @param sampler Noise sampler to use * @param sampler Noise sampler to use
*/ */
public PaletteLayer(E type, NoiseSampler sampler) { public PaletteLayer(BlockData type, NoiseSampler sampler) {
this.sampler = sampler; this.sampler = sampler;
this.col = false; this.col = false;
this.m = type; this.m = type;
@@ -94,18 +95,18 @@ public abstract class Palette<E> {
* *
* @return Material - the material.. * @return Material - the material..
*/ */
public E get(Random random) { public BlockData get(Random random) {
if(col) return this.collection.get(random); if(col) return this.collection.get(random);
return m; return m;
} }
public E get(NoiseSampler random, double x, double y, double z, boolean is2D) { public BlockData get(NoiseSampler random, double x, double y, double z, boolean is2D) {
if(col && is2D) return this.collection.get(random, x, z); if(col && is2D) return this.collection.get(random, x, z);
else if(col) return this.collection.get(random, x, y, z); else if(col) return this.collection.get(random, x, y, z);
return m; return m;
} }
public ProbabilityCollection<E> getCollection() { public ProbabilityCollection<BlockData> getCollection() {
return collection; return collection;
} }
} }
@@ -1,14 +1,16 @@
package com.dfsek.terra.api.world.palette; package com.dfsek.terra.api.world.palette;
public class SinglePalette<E> extends Palette<E> { import com.dfsek.terra.api.platform.block.BlockData;
private final E item;
public SinglePalette(E item) { public class SinglePalette extends Palette {
private final BlockData item;
public SinglePalette(BlockData item) {
this.item = item; this.item = item;
} }
@Override @Override
public E get(int layer, double x, double y, double z) { public BlockData get(int layer, double x, double y, double z) {
return item; return item;
} }
} }
@@ -1,16 +1,15 @@
package com.dfsek.terra.api.world.palette.holder; package com.dfsek.terra.api.world.palette.holder;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
public class PaletteHolder { public class PaletteHolder {
private final Palette<BlockData>[] palettes; private final Palette[] palettes;
protected PaletteHolder(Palette<BlockData>[] palettes) { protected PaletteHolder(Palette[] palettes) {
this.palettes = palettes; this.palettes = palettes;
} }
public Palette<BlockData> getPalette(int y) { public Palette getPalette(int y) {
return palettes[y]; return palettes[y];
} }
} }
@@ -1,6 +1,5 @@
package com.dfsek.terra.api.world.palette.holder; package com.dfsek.terra.api.world.palette.holder;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import net.jafama.FastMath; import net.jafama.FastMath;
@@ -8,19 +7,19 @@ import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
public class PaletteHolderBuilder { public class PaletteHolderBuilder {
private final TreeMap<Integer, Palette<BlockData>> paletteMap = new TreeMap<>(); private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
public PaletteHolderBuilder add(int y, Palette<BlockData> palette) { public PaletteHolderBuilder add(int y, Palette palette) {
paletteMap.put(y, palette); paletteMap.put(y, palette);
return this; return this;
} }
@SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"}) @SuppressWarnings({"unchecked", "rawtypes", "RedundantSuppression"})
public PaletteHolder build() { public PaletteHolder build() {
Palette<BlockData>[] palettes = new Palette[paletteMap.lastKey() + 1]; Palette[] palettes = new Palette[paletteMap.lastKey() + 1];
for(int y = 0; y <= FastMath.max(paletteMap.lastKey(), 255); y++) { for(int y = 0; y <= FastMath.max(paletteMap.lastKey(), 255); y++) {
Palette<BlockData> d = null; Palette d = null;
for(Map.Entry<Integer, Palette<BlockData>> e : paletteMap.entrySet()) { for(Map.Entry<Integer, Palette> e : paletteMap.entrySet()) {
if(e.getKey() >= y) { if(e.getKey() >= y) {
d = e.getValue(); d = e.getValue();
break; break;
@@ -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.getWorld()).getConfig().getBiomeRegistry().get(arg); return main.getWorld(player.getWorld()).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.getWorld()).getConfig().getBiomeRegistry().entries().stream().map(TerraBiome::getID).collect(Collectors.toList()); return main.getWorld(player.getWorld()).getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
} }
} }
@@ -13,6 +13,6 @@ public class ScriptArgumentParser implements ArgumentParser<StructureScript> {
@Override @Override
public StructureScript parse(CommandSender sender, String arg) { public StructureScript parse(CommandSender sender, String arg) {
return main.getWorld(((Player) sender).getWorld()).getConfig().getScriptRegistry().get(arg); return main.getWorld(((Player) sender).getWorld()).getConfig().getRegistry(StructureScript.class).get(arg);
} }
} }
@@ -13,6 +13,6 @@ public class StructureArgumentParser implements ArgumentParser<TerraStructure> {
@Override @Override
public TerraStructure parse(CommandSender sender, String arg) { public TerraStructure parse(CommandSender sender, String arg) {
return main.getWorld(((Player) sender).getWorld()).getConfig().getStructureRegistry().get(arg); return main.getWorld(((Player) sender).getWorld()).getConfig().getRegistry(TerraStructure.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).getWorld()).getConfig().getScriptRegistry().entries().stream().map(StructureScript::getId).collect(Collectors.toList()); return main.getWorld(((Player) sender).getWorld()).getConfig().getRegistry(StructureScript.class).entries().stream().map(StructureScript::getId).collect(Collectors.toList());
} }
} }
@@ -5,6 +5,7 @@ import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.injection.annotations.Inject; import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender; import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player; import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.world.population.items.TerraStructure;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -16,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.getWorld()).getConfig().getStructureRegistry().keys()); return new ArrayList<>(main.getWorld(player.getWorld()).getConfig().getRegistry(TerraStructure.class).keys());
} }
} }
@@ -2,7 +2,6 @@ package com.dfsek.terra.config.factories;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler; import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.flora.Flora; import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.NoisePalette; import com.dfsek.terra.api.world.palette.NoisePalette;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
@@ -13,7 +12,7 @@ import com.dfsek.terra.world.population.items.flora.TerraFlora;
public class FloraFactory implements ConfigFactory<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 palette = new NoisePalette(new WhiteNoiseSampler(2403), false);
for(PaletteLayerHolder layer : config.getFloraPalette()) { for(PaletteLayerHolder layer : config.getFloraPalette()) {
palette.add(layer.getLayer(), layer.getSize(), layer.getSampler()); palette.add(layer.getLayer(), layer.getSize(), layer.getSampler());
} }
@@ -1,16 +1,15 @@
package com.dfsek.terra.config.factories; package com.dfsek.terra.config.factories;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.NoisePalette; import com.dfsek.terra.api.world.palette.NoisePalette;
import com.dfsek.terra.api.world.palette.Palette; 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 ConfigFactory<PaletteTemplate, Palette<BlockData>> { public class PaletteFactory implements ConfigFactory<PaletteTemplate, Palette> {
@Override @Override
public Palette<BlockData> build(PaletteTemplate config, TerraPlugin main) { public Palette build(PaletteTemplate config, TerraPlugin main) {
NoisePalette<BlockData> palette = new NoisePalette<>(config.getNoise().apply(2403L), config.getNoise().getDimensions() == 2); NoisePalette palette = new NoisePalette(config.getNoise().apply(2403L), config.getNoise().getDimensions() == 2);
for(PaletteLayerHolder layer : config.getPalette()) { for(PaletteLayerHolder layer : config.getPalette()) {
palette.add(layer.getLayer(), layer.getSize(), layer.getSampler()); palette.add(layer.getLayer(), layer.getSize(), layer.getSampler());
} }
@@ -30,7 +30,7 @@ public class ZIPLoader extends Loader {
ZipEntry entry = entries.nextElement(); ZipEntry entry = entries.nextElement();
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) { if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) {
try { try {
String rel = entry.getName().substring(directory.length() + 1); String rel = entry.getName().substring(directory.length());
streams.put(rel, file.getInputStream(entry)); streams.put(rel, file.getInputStream(entry));
} catch(IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -5,7 +5,6 @@ import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.util.collections.ProbabilityCollection; import com.dfsek.terra.api.util.collections.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.flora.Flora; import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
@@ -15,7 +14,6 @@ import java.util.Map;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Types { public final class Types {
public static final Type BLOCK_DATA_PALETTE_TYPE;
public static final Type BLOCK_DATA_PROBABILITY_COLLECTION_TYPE; public static final Type BLOCK_DATA_PROBABILITY_COLLECTION_TYPE;
public static final Type FLORA_PROBABILITY_COLLECTION_TYPE; public static final Type FLORA_PROBABILITY_COLLECTION_TYPE;
public static final Type TREE_PROBABILITY_COLLECTION_TYPE; public static final Type TREE_PROBABILITY_COLLECTION_TYPE;
@@ -23,7 +21,6 @@ public final class Types {
public static final Type TERRA_BIOME_TERRA_BIOME_PROBABILITY_COLLECTION_MAP; public static final Type TERRA_BIOME_TERRA_BIOME_PROBABILITY_COLLECTION_MAP;
static { static {
BLOCK_DATA_PALETTE_TYPE = getType("blockDataPalette");
BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection"); BLOCK_DATA_PROBABILITY_COLLECTION_TYPE = getType("blockDataProbabilityCollection");
FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection"); FLORA_PROBABILITY_COLLECTION_TYPE = getType("floraProbabilityCollection");
TREE_PROBABILITY_COLLECTION_TYPE = getType("treeProbabilityCollection"); TREE_PROBABILITY_COLLECTION_TYPE = getType("treeProbabilityCollection");
@@ -31,7 +28,6 @@ public final class Types {
TERRA_BIOME_TERRA_BIOME_PROBABILITY_COLLECTION_MAP = getType("terraBiomeProbabilityCollectionMap"); TERRA_BIOME_TERRA_BIOME_PROBABILITY_COLLECTION_MAP = getType("terraBiomeProbabilityCollectionMap");
} }
private Palette<BlockData> blockDataPalette;
private ProbabilityCollection<BlockData> blockDataProbabilityCollection; private ProbabilityCollection<BlockData> blockDataProbabilityCollection;
private ProbabilityCollection<Flora> floraProbabilityCollection; private ProbabilityCollection<Flora> floraProbabilityCollection;
private ProbabilityCollection<Tree> treeProbabilityCollection; private ProbabilityCollection<Tree> treeProbabilityCollection;
@@ -6,8 +6,9 @@ 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.tectonic.loading.object.ObjectTemplate; import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.seeded.NoiseProvider;
import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.registry.config.NoiseRegistry;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Locale; import java.util.Locale;
@@ -15,9 +16,9 @@ import java.util.Map;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> { public class NoiseSamplerBuilderLoader implements TypeLoader<NoiseSeeded> {
private final NoiseRegistry noiseRegistry; private final Registry<NoiseProvider> noiseRegistry;
public NoiseSamplerBuilderLoader(NoiseRegistry noiseRegistry) { public NoiseSamplerBuilderLoader(Registry<NoiseProvider> noiseRegistry) {
this.noiseRegistry = noiseRegistry; this.noiseRegistry = noiseRegistry;
} }
@@ -3,11 +3,9 @@ package com.dfsek.terra.config.loaders.palette;
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.tectonic.loading.TypeLoader; import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
import com.dfsek.terra.api.world.palette.holder.PaletteHolderBuilder; import com.dfsek.terra.api.world.palette.holder.PaletteHolderBuilder;
import com.dfsek.terra.config.loaders.Types;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
@@ -21,7 +19,7 @@ public class PaletteHolderLoader implements TypeLoader<PaletteHolder> {
PaletteHolderBuilder builder = new PaletteHolderBuilder(); PaletteHolderBuilder builder = new PaletteHolderBuilder();
for(Map<String, Integer> layer : palette) { for(Map<String, Integer> layer : palette) {
for(Map.Entry<String, Integer> entry : layer.entrySet()) { for(Map.Entry<String, Integer> entry : layer.entrySet()) {
builder.add(entry.getValue(), (Palette<BlockData>) configLoader.loadType(Types.BLOCK_DATA_PALETTE_TYPE, entry.getKey())); builder.add(entry.getValue(), (Palette) configLoader.loadType(Palette.class, entry.getKey()));
} }
} }
return builder.build(); return builder.build();
@@ -2,36 +2,27 @@ package com.dfsek.terra.config.pack;
import com.dfsek.paralithic.eval.parser.Scope; import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.tectonic.abstraction.AbstractConfigLoader; import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.config.Configuration;
import com.dfsek.tectonic.exception.ConfigException; import com.dfsek.tectonic.exception.ConfigException;
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.tectonic.loading.TypeRegistry; import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.LoaderRegistrar; import com.dfsek.terra.api.LoaderRegistrar;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.event.events.config.ConfigPackPostLoadEvent; import com.dfsek.terra.api.event.events.config.ConfigPackPostLoadEvent;
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.Tree;
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.structures.loot.LootTable; import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.StructureScript; import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.util.generic.pair.ImmutablePair;
import com.dfsek.terra.api.util.seeded.NoiseProvider;
import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider; 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.carving.UserDefinedCarver;
import com.dfsek.terra.config.builder.BiomeBuilder; import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.dummy.DummyWorld; import com.dfsek.terra.config.dummy.DummyWorld;
import com.dfsek.terra.config.factories.BiomeFactory;
import com.dfsek.terra.config.factories.CarverFactory;
import com.dfsek.terra.config.factories.ConfigFactory;
import com.dfsek.terra.config.factories.FloraFactory;
import com.dfsek.terra.config.factories.OreFactory;
import com.dfsek.terra.config.factories.PaletteFactory;
import com.dfsek.terra.config.factories.StructureFactory;
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;
import com.dfsek.terra.config.fileloaders.ZIPLoader; import com.dfsek.terra.config.fileloaders.ZIPLoader;
@@ -41,29 +32,16 @@ import com.dfsek.terra.config.loaders.config.biome.templates.provider.ImageProvi
import com.dfsek.terra.config.loaders.config.biome.templates.provider.SingleBiomeProviderTemplate; import com.dfsek.terra.config.loaders.config.biome.templates.provider.SingleBiomeProviderTemplate;
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader; import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
import com.dfsek.terra.config.templates.AbstractableTemplate; import com.dfsek.terra.config.prototype.ConfigType;
import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.prototype.ProtoConfig;
import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.config.templates.FloraTemplate;
import com.dfsek.terra.config.templates.OreTemplate;
import com.dfsek.terra.config.templates.PaletteTemplate;
import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
import com.dfsek.terra.registry.config.BiomeRegistry; import com.dfsek.terra.registry.config.ConfigTypeRegistry;
import com.dfsek.terra.registry.config.CarverRegistry;
import com.dfsek.terra.registry.config.FloraRegistry;
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.NoiseRegistry; import com.dfsek.terra.registry.config.NoiseRegistry;
import com.dfsek.terra.registry.config.OreRegistry;
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.TreeRegistry;
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;
import com.dfsek.terra.world.population.items.ores.Ore;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -74,12 +52,14 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
@@ -89,38 +69,27 @@ import java.util.zip.ZipFile;
public class ConfigPack implements LoaderRegistrar { public class ConfigPack implements LoaderRegistrar {
private final ConfigPackTemplate template = new ConfigPackTemplate(); private final ConfigPackTemplate template = new ConfigPackTemplate();
private final BiomeRegistry biomeRegistry = new BiomeRegistry();
private final StructureRegistry structureRegistry = new StructureRegistry();
private final PaletteRegistry paletteRegistry;
private final FloraRegistry floraRegistry;
private final OreRegistry oreRegistry = new OreRegistry();
private final TreeRegistry treeRegistry;
private final ScriptRegistry scriptRegistry = new ScriptRegistry();
private final LootRegistry lootRegistry = new LootRegistry();
private final CarverRegistry carverRegistry = new CarverRegistry();
private final NoiseRegistry noiseRegistry = new NoiseRegistry();
private final FunctionRegistry functionRegistry = new FunctionRegistry();
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader(); private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
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 TerraPlugin main; private final TerraPlugin main;
private final Loader loader; private final Loader loader;
private final BiomeProvider.BiomeProviderBuilder biomeProviderBuilder; private final BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
private final ConfigTypeRegistry configTypeRegistry;
private final Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> registryMap = newRegistryMap();
public ConfigPack(File folder, TerraPlugin main) throws ConfigException { public ConfigPack(File folder, TerraPlugin main) throws ConfigException {
try { try {
this.configTypeRegistry = new ConfigTypeRegistry(this, main, (id, configType) -> {
OpenRegistry<?> openRegistry = configType.registrySupplier().get();
registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistry<>(openRegistry)));
});
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();
floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry();
register(abstractConfigLoader); register(abstractConfigLoader);
register(selfLoader); register(selfLoader);
@@ -139,6 +108,7 @@ public class ConfigPack implements LoaderRegistrar {
selfLoader.load(packPostTemplate, new FileInputStream(pack)); selfLoader.load(packPostTemplate, new FileInputStream(pack));
biomeProviderBuilder = packPostTemplate.getProviderBuilder(); biomeProviderBuilder = packPostTemplate.getProviderBuilder();
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time. biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
checkDeadEntries(main);
} catch(FileNotFoundException e) { } catch(FileNotFoundException e) {
throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e); throw new LoadException("No pack.yml file found in " + folder.getAbsolutePath(), e);
} }
@@ -151,17 +121,16 @@ public class ConfigPack implements LoaderRegistrar {
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException { public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
try { try {
this.configTypeRegistry = new ConfigTypeRegistry(this, main, (id, configType) -> {
OpenRegistry<?> openRegistry = configType.registrySupplier().get();
registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistry<>(openRegistry)));
});
this.loader = new ZIPLoader(file); this.loader = new ZIPLoader(file);
this.main = main; this.main = main;
long l = System.nanoTime(); long l = System.nanoTime();
floraRegistry = new FloraRegistry(main);
paletteRegistry = new PaletteRegistry(main);
treeRegistry = new TreeRegistry();
register(abstractConfigLoader);
register(selfLoader);
register(selfLoader);
main.register(selfLoader); main.register(selfLoader);
main.register(abstractConfigLoader);
try { try {
ZipEntry pack = null; ZipEntry pack = null;
@@ -183,6 +152,7 @@ public class ConfigPack implements LoaderRegistrar {
selfLoader.load(packPostTemplate, file.getInputStream(pack)); selfLoader.load(packPostTemplate, file.getInputStream(pack));
biomeProviderBuilder = packPostTemplate.getProviderBuilder(); biomeProviderBuilder = packPostTemplate.getProviderBuilder();
biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time. biomeProviderBuilder.build(0); // Build dummy provider to catch errors at load time.
checkDeadEntries(main);
} catch(IOException e) { } catch(IOException e) {
throw new LoadException("Unable to load pack.yml from ZIP file", e); throw new LoadException("Unable to load pack.yml from ZIP file", e);
} }
@@ -194,10 +164,36 @@ public class ConfigPack implements LoaderRegistrar {
toWorldConfig(new TerraWorld(new DummyWorld(), this, main)); // Build now to catch any errors immediately. toWorldConfig(new TerraWorld(new DummyWorld(), this, main)); // Build now to catch any errors immediately.
} }
public static <C extends AbstractableTemplate, O> void buildAll(ConfigFactory<C, O> factory, OpenRegistry<O> registry, List<C> configTemplates, TerraPlugin main) throws LoadException { @SuppressWarnings({"unchecked", "rawtypes"})
for(C template : configTemplates) registry.add(template.getID(), factory.build(template, main)); private Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> newRegistryMap() {
Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> map = new HashMap<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>>() {
private static final long serialVersionUID = 4015855819914064466L;
@Override
public ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>> put(Class<?> key, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>> value) {
selfLoader.registerLoader(key, value.getLeft());
abstractConfigLoader.registerLoader(key, value.getLeft());
return super.put(key, value);
}
};
putPair(map, NoiseProvider.class, new NoiseRegistry());
putPair(map, FunctionBuilder.class, (OpenRegistry<FunctionBuilder>) (Object) new FunctionRegistry());
putPair(map, LootTable.class, new LootRegistry());
putPair(map, StructureScript.class, new ScriptRegistry());
return map;
} }
private <R> void putPair(Map<Class<?>, ImmutablePair<OpenRegistry<?>, CheckedRegistry<?>>> map, Class<R> key, OpenRegistry<R> l) {
map.put(key, ImmutablePair.of(l, new CheckedRegistry<>(l)));
}
private void checkDeadEntries(TerraPlugin main) {
registryMap.forEach((clazz, pair) -> pair.getLeft().getDeadEntries().forEach((id, value) -> main.getDebugLogger().warn("Dead entry in '" + clazz + "' registry: '" + id + "'")));
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void load(long start, TerraPlugin main) throws ConfigException { private void load(long start, TerraPlugin main) throws ConfigException {
main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this)); main.getEventManager().callEvent(new ConfigPackPreLoadEvent(this));
@@ -208,8 +204,8 @@ 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(InputStream stream = entry.getValue()) { try(InputStream stream = entry.getValue()) {
StructureScript structureScript = new StructureScript(stream, main, scriptRegistry, lootRegistry, functionRegistry); StructureScript structureScript = new StructureScript(stream, main, getRegistry(StructureScript.class), getRegistry(LootTable.class), (Registry<FunctionBuilder<?>>) (Object) getRegistry(FunctionBuilder.class));
scriptRegistry.add(structureScript.getId(), structureScript); getOpenRegistry(StructureScript.class).add(structureScript.getId(), structureScript);
} catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException | IOException 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);
} }
@@ -217,36 +213,38 @@ public class ConfigPack implements LoaderRegistrar {
}).close().open("structures/loot", ".json").thenEntries(entries -> { }).close().open("structures/loot", ".json").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) { for(Map.Entry<String, InputStream> entry : entries) {
try { try {
lootRegistry.add(entry.getKey(), new LootTable(IOUtils.toString(entry.getValue(), StandardCharsets.UTF_8), main)); getOpenRegistry(LootTable.class).add(entry.getKey(), new LootTable(IOUtils.toString(entry.getValue(), StandardCharsets.UTF_8), main));
} catch(ParseException | IOException | NullPointerException e) { } catch(ParseException | IOException | NullPointerException e) {
throw new LoadException("Unable to load loot table \"" + entry.getKey() + "\"", e); throw new LoadException("Unable to load loot table \"" + entry.getKey() + "\"", e);
} }
} }
}).close(); }).close();
loader List<Configuration> configurations = new ArrayList<>();
.open("carving", ".yml").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new), main)).close()
.open("palettes", ".yml").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new), main)).close() loader.open("", ".yml").thenEntries(entries -> entries.forEach(stream -> configurations.add(new Configuration(stream.getValue(), stream.getKey()))));
.open("ores", ".yml").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new), main)).close()
.open("structures/trees", ".yml").then(streams -> buildAll(new TreeFactory(), treeRegistry, abstractConfigLoader.load(streams, TreeTemplate::new), main)).close() Map<ConfigType<? extends ConfigTemplate, ?>, List<Configuration>> configs = new HashMap<>();
.open("structures/structures", ".yml").then(streams -> buildAll(new StructureFactory(), structureRegistry, abstractConfigLoader.load(streams, StructureTemplate::new), main)).close()
.open("flora", ".yml").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new), main)).close() for(Configuration configuration : configurations) {
.open("biomes", ".yml").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this, main)), main)).close(); ProtoConfig config = new ProtoConfig();
selfLoader.load(config, configuration);
configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration);
}
for(ConfigType<?, ?> configType : configTypeRegistry.entries()) {
for(ConfigTemplate config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()), () -> configType.getTemplate(this, main))) {
((ConfigType) configType).callback(this, main, config);
}
}
main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this)); main.getEventManager().callEvent(new ConfigPackPostLoadEvent(this));
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 TerraStructure getStructure(String id) {
return structureRegistry.get(id);
}
public Set<TerraStructure> getStructures() { public Set<TerraStructure> getStructures() {
return structureRegistry.entries(); return new HashSet<>(getRegistry(TerraStructure.class).entries());
}
public List<String> getStructureIDs() {
return structureRegistry.entries().stream().map(terraStructure -> terraStructure.getTemplate().getID()).collect(Collectors.toList());
} }
public ConfigPackTemplate getTemplate() { public ConfigPackTemplate getTemplate() {
@@ -257,80 +255,45 @@ public class ConfigPack implements LoaderRegistrar {
return varScope; return varScope;
} }
@SuppressWarnings("unchecked")
public <T> CheckedRegistry<T> getRegistry(Class<T> clazz) {
return (CheckedRegistry<T>) registryMap.getOrDefault(clazz, ImmutablePair.ofNull()).getRight();
}
@SuppressWarnings("unchecked")
protected <T> OpenRegistry<T> getOpenRegistry(Class<T> clazz) {
return (OpenRegistry<T>) registryMap.getOrDefault(clazz, ImmutablePair.ofNull()).getLeft();
}
@Override @Override
public void register(TypeRegistry registry) { public void register(TypeRegistry registry) {
registry registry
.registerLoader(Palette.class, paletteRegistry) .registerLoader(ConfigType.class, configTypeRegistry)
.registerLoader(BiomeBuilder.class, biomeRegistry)
.registerLoader(Flora.class, floraRegistry)
.registerLoader(Ore.class, oreRegistry)
.registerLoader(Tree.class, treeRegistry)
.registerLoader(StructureScript.class, scriptRegistry)
.registerLoader(TerraStructure.class, structureRegistry)
.registerLoader(LootTable.class, lootRegistry)
.registerLoader(UserDefinedCarver.class, carverRegistry)
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader)) .registerLoader(BufferedImage.class, new BufferedImageLoader(loader))
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(noiseRegistry))
.registerLoader(SingleBiomeProviderTemplate.class, SingleBiomeProviderTemplate::new) .registerLoader(SingleBiomeProviderTemplate.class, SingleBiomeProviderTemplate::new)
.registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(main)) .registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(main))
.registerLoader(ImageProviderTemplate.class, () -> new ImageProviderTemplate(biomeRegistry)) .registerLoader(ImageProviderTemplate.class, () -> new ImageProviderTemplate(getRegistry(BiomeBuilder.class)))
.registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry)); .registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(getRegistry(BiomeBuilder.class)))
} .registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(getOpenRegistry(NoiseProvider.class)));
public Set<UserDefinedCarver> getCarvers() {
return carverRegistry.entries();
} }
public BiomeProvider.BiomeProviderBuilder getBiomeProviderBuilder() { public BiomeProvider.BiomeProviderBuilder getBiomeProviderBuilder() {
return biomeProviderBuilder; return biomeProviderBuilder;
} }
public CheckedRegistry<StructureScript> getScriptRegistry() {
return new CheckedRegistry<>(scriptRegistry);
}
public CheckedRegistry<BiomeBuilder> getBiomeRegistry() { public WorldConfig toWorldConfig(TerraWorld world) {
return new CheckedRegistry<>(biomeRegistry);
}
public CheckedRegistry<Tree> getTreeRegistry() {
return new CheckedRegistry<>(treeRegistry);
}
public CheckedRegistry<FunctionBuilder<?>> getFunctionRegistry() {
return new CheckedRegistry<>(functionRegistry);
}
public CheckedRegistry<Supplier<ObjectTemplate<NoiseSeeded>>> getNormalizerRegistry() {
return new CheckedRegistry<>(noiseRegistry);
}
public CheckedRegistry<UserDefinedCarver> getCarverRegistry() {
return new CheckedRegistry<>(carverRegistry);
}
public CheckedRegistry<Flora> getFloraRegistry() {
return new CheckedRegistry<>(floraRegistry);
}
public CheckedRegistry<LootTable> getLootRegistry() {
return new CheckedRegistry<>(lootRegistry);
}
public CheckedRegistry<Ore> getOreRegistry() {
return new CheckedRegistry<>(oreRegistry);
}
public CheckedRegistry<Palette<BlockData>> getPaletteRegistry() {
return new CheckedRegistry<>(paletteRegistry);
}
public CheckedRegistry<TerraStructure> getStructureRegistry() {
return new CheckedRegistry<>(structureRegistry);
}
public WorldConfig toWorldConfig(TerraWorld world){
return new WorldConfig(world, this, main); return new WorldConfig(world, this, main);
} }
public CheckedRegistry<ConfigType<?, ?>> getConfigTypeRegistry() {
return new CheckedRegistry<ConfigType<?, ?>>(configTypeRegistry) {
@Override
@SuppressWarnings("deprecation")
public void addUnchecked(String identifier, ConfigType<?, ?> value) {
if(contains(identifier)) throw new UnsupportedOperationException("Cannot override values in ConfigTypeRegistry!");
}
};
}
} }
@@ -1,62 +1,51 @@
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.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.registry.LockedRegistry; import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.structures.loot.LootTable;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.world.biome.TerraBiome; 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.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.carving.UserDefinedCarver; import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
import com.dfsek.terra.world.TerraWorld; import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.generation.math.SamplerCache; import com.dfsek.terra.world.generation.math.SamplerCache;
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 java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
public class WorldConfig { public class WorldConfig {
private final LockedRegistry<StructureScript> scriptRegistry;
private final LockedRegistry<TerraBiome> biomeRegistry;
private final SamplerCache samplerCache; 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 BiomeProvider provider;
private final TerraWorld world; private final TerraWorld world;
private final ConfigPack pack; private final ConfigPack pack;
private final Map<Class<?>, LockedRegistry<?>> registryMap = new HashMap<>();
public WorldConfig(TerraWorld world, ConfigPack pack, TerraPlugin main) { public WorldConfig(TerraWorld world, ConfigPack pack, TerraPlugin main) {
this.world = world; this.world = world;
this.pack = pack; this.pack = pack;
this.samplerCache = new SamplerCache(main, world); this.samplerCache = new SamplerCache(main, world);
this.scriptRegistry = new LockedRegistry<>(pack.getScriptRegistry());
pack.getConfigTypeRegistry().forEach(configType -> registryMap.put(configType.getTypeClass(), new LockedRegistry<>(pack.getRegistry(configType.getTypeClass()))));
OpenRegistry<TerraBiome> biomeOpenRegistry = new OpenRegistry<>(); OpenRegistry<TerraBiome> biomeOpenRegistry = new OpenRegistry<>();
pack.getBiomeRegistry().forEach((id, biome) -> biomeOpenRegistry.add(id, biome.apply(world.getWorld().getSeed()))); pack.getRegistry(BiomeBuilder.class).forEach((id, biome) -> biomeOpenRegistry.add(id, biome.apply(world.getWorld().getSeed())));
registryMap.put(TerraBiome.class, new LockedRegistry<>(biomeOpenRegistry));
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()); this.provider = pack.getBiomeProviderBuilder().build(world.getWorld().getSeed());
} }
@SuppressWarnings("unchecked")
public <T> LockedRegistry<T> getRegistry(Class<T> clazz) {
return (LockedRegistry<T>) registryMap.get(clazz);
}
public TerraWorld getWorld() { public TerraWorld getWorld() {
return world; return world;
} }
@@ -66,43 +55,7 @@ public class WorldConfig {
} }
public Set<UserDefinedCarver> getCarvers() { public Set<UserDefinedCarver> getCarvers() {
return carverRegistry.entries(); return new HashSet<>(getRegistry(UserDefinedCarver.class).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() { public BiomeProvider getProvider() {
@@ -110,7 +63,7 @@ public class WorldConfig {
} }
public Set<TerraStructure> getStructures() { public Set<TerraStructure> getStructures() {
return structureRegistry.entries(); return new HashSet<>(getRegistry(TerraStructure.class).entries());
} }
public ConfigPackTemplate getTemplate() { public ConfigPackTemplate getTemplate() {
@@ -0,0 +1,19 @@
package com.dfsek.terra.config.prototype;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.registry.OpenRegistry;
import java.util.function.Supplier;
public interface ConfigType<T extends ConfigTemplate, R> {
T getTemplate(ConfigPack pack, TerraPlugin main);
void callback(ConfigPack pack, TerraPlugin main, T loadedConfig) throws LoadException;
Class<R> getTypeClass();
Supplier<OpenRegistry<R>> registrySupplier();
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.config.prototype;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
public class ProtoConfig implements ConfigTemplate {
@Value("id")
private String id;
@Value("type")
private ConfigType<?, ?> type;
public String getId() {
return id;
}
public ConfigType<?, ?> getType() {
return type;
}
}
@@ -13,7 +13,6 @@ 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.math.paralithic.BlankFunction; import com.dfsek.terra.api.math.paralithic.BlankFunction;
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction; import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.api.platform.world.Biome; import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.util.GlueList; import com.dfsek.terra.api.util.GlueList;
@@ -124,7 +123,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Value("ocean.palette") @Value("ocean.palette")
@Abstractable @Abstractable
@Default @Default
private Palette<BlockData> oceanPalette; private Palette oceanPalette;
@Value("elevation.equation") @Value("elevation.equation")
@Default @Default
@@ -159,12 +158,12 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
@Value("slabs.palettes") @Value("slabs.palettes")
@Abstractable @Abstractable
@Default @Default
private Map<BlockType, Palette<BlockData>> slabPalettes; private Map<BlockType, Palette> slabPalettes;
@Value("slabs.stair-palettes") @Value("slabs.stair-palettes")
@Abstractable @Abstractable
@Default @Default
private Map<BlockType, Palette<BlockData>> stairPalettes; private Map<BlockType, Palette> stairPalettes;
@Value("slant.threshold") @Value("slant.threshold")
@Abstractable @Abstractable
@@ -247,14 +246,6 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
return doSlabs; return doSlabs;
} }
public Map<BlockType, Palette<BlockData>> getSlabPalettes() {
return slabPalettes;
}
public Map<BlockType, Palette<BlockData>> getStairPalettes() {
return stairPalettes;
}
public BiomeTemplate(ConfigPack pack, TerraPlugin main) { public BiomeTemplate(ConfigPack pack, TerraPlugin main) {
this.pack = pack; this.pack = pack;
biomeNoise = new NoiseSeeded() { biomeNoise = new NoiseSeeded() {
@@ -268,7 +259,15 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
return 2; return 2;
} }
}; };
oceanPalette = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:water")); oceanPalette = new SinglePalette(main.getWorldHandle().createBlockData("minecraft:water"));
}
public Map<BlockType, Palette> getSlabPalettes() {
return slabPalettes;
}
public Map<BlockType, Palette> getStairPalettes() {
return stairPalettes;
} }
public NoiseSeeded getBiomeNoise() { public NoiseSeeded getBiomeNoise() {
@@ -291,7 +290,7 @@ public class BiomeTemplate extends AbstractableTemplate implements ValidatedConf
return seaLevel; return seaLevel;
} }
public Palette<BlockData> getOceanPalette() { public Palette getOceanPalette() {
return oceanPalette; return oceanPalette;
} }
@@ -17,7 +17,7 @@ public class OreTemplate extends AbstractableTemplate {
@Abstractable @Abstractable
private BlockData material; private BlockData material;
@Value("type") @Value("algorithm")
@Abstractable @Abstractable
@Default @Default
private Ore.Type oreType = Ore.Type.VANILLA; private Ore.Type oreType = Ore.Type.VANILLA;
@@ -6,19 +6,30 @@ import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.registry.exception.DuplicateEntryException; import com.dfsek.terra.registry.exception.DuplicateEntryException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
/** /**
* 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 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, Entry<T>> objects;
private static final Entry<?> NULL = new Entry<>(null);
public OpenRegistry() {
objects = new HashMap<>();
}
protected OpenRegistry(Map<String, Entry<T>> init) {
this.objects = init;
}
@Override @Override
public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException { public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
@@ -35,6 +46,10 @@ public class OpenRegistry<T> implements Registry<T> {
* @param value Value to add. * @param value Value to add.
*/ */
public boolean add(String identifier, T value) { public boolean add(String identifier, T value) {
return add(identifier, new Entry<>(value));
}
protected boolean add(String identifier, Entry<T> value) {
boolean exists = objects.containsKey(identifier); boolean exists = objects.containsKey(identifier);
objects.put(identifier, value); objects.put(identifier, value);
return exists; return exists;
@@ -58,24 +73,25 @@ public class OpenRegistry<T> implements Registry<T> {
return objects.containsKey(identifier); return objects.containsKey(identifier);
} }
@SuppressWarnings("unchecked")
@Override @Override
public T get(String identifier) { public T get(String identifier) {
return objects.get(identifier); return objects.getOrDefault(identifier, (Entry<T>) NULL).getValue();
} }
@Override @Override
public void forEach(Consumer<T> consumer) { public void forEach(Consumer<T> consumer) {
objects.forEach((id, obj) -> consumer.accept(obj)); objects.forEach((id, obj) -> consumer.accept(obj.getRaw()));
} }
@Override @Override
public void forEach(BiConsumer<String, T> consumer) { public void forEach(BiConsumer<String, T> consumer) {
objects.forEach(consumer); objects.forEach((id, entry) -> consumer.accept(id, entry.getRaw()));
} }
@Override @Override
public Set<T> entries() { public Collection<T> entries() {
return new HashSet<>(objects.values()); return objects.values().stream().map(Entry::getRaw).collect(Collectors.toList());
} }
@Override @Override
@@ -83,10 +99,41 @@ public class OpenRegistry<T> implements Registry<T> {
return objects.keySet(); return objects.keySet();
} }
public Map<String, T> getDeadEntries() {
Map<String, T> dead = new HashMap<>();
objects.forEach((id, entry) -> {
if(entry.dead()) dead.put(id, entry.value); // dont increment value here.
});
return dead;
}
/** /**
* Clears all entries from the registry. * Clears all entries from the registry.
*/ */
public void clear() { public void clear() {
objects.clear(); objects.clear();
} }
protected static final class Entry<T> {
private final T value;
private final AtomicInteger access = new AtomicInteger(0);
public Entry(T value) {
this.value = value;
}
public T getValue() {
access.incrementAndGet();
return value;
}
private T getRaw() {
return value;
}
public boolean dead() {
return access.get() == 0;
}
}
} }
@@ -0,0 +1,117 @@
package com.dfsek.terra.registry.config;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.world.flora.Flora;
import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.factories.BiomeFactory;
import com.dfsek.terra.config.factories.CarverFactory;
import com.dfsek.terra.config.factories.ConfigFactory;
import com.dfsek.terra.config.factories.FloraFactory;
import com.dfsek.terra.config.factories.OreFactory;
import com.dfsek.terra.config.factories.PaletteFactory;
import com.dfsek.terra.config.factories.StructureFactory;
import com.dfsek.terra.config.factories.TreeFactory;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.prototype.ConfigType;
import com.dfsek.terra.config.templates.AbstractableTemplate;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.config.templates.FloraTemplate;
import com.dfsek.terra.config.templates.OreTemplate;
import com.dfsek.terra.config.templates.PaletteTemplate;
import com.dfsek.terra.config.templates.StructureTemplate;
import com.dfsek.terra.config.templates.TreeTemplate;
import com.dfsek.terra.registry.OpenRegistry;
import com.dfsek.terra.world.population.items.TerraStructure;
import com.dfsek.terra.world.population.items.ores.Ore;
import java.util.LinkedHashMap;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
public class ConfigTypeRegistry extends OpenRegistry<ConfigType<?, ?>> {
private final BiConsumer<String, ConfigType<?, ?>> callback;
public ConfigTypeRegistry(ConfigPack pack, TerraPlugin main, BiConsumer<String, ConfigType<?, ?>> callback) {
super(new LinkedHashMap<>()); // Ordered
this.callback = callback;
add("PALETTE", new ConfigBuilder<>(new PaletteFactory(), PaletteTemplate::new, Palette.class, () -> new PaletteRegistry(main)));
add("ORE", new ConfigBuilder<>(new OreFactory(), OreTemplate::new, Ore.class, OreRegistry::new));
add("FLORA", new ConfigBuilder<>(new FloraFactory(), FloraTemplate::new, Flora.class, () -> new FloraRegistry(main)));
add("CARVER", new ConfigBuilder<>(new CarverFactory(pack), CarverTemplate::new, UserDefinedCarver.class, CarverRegistry::new));
add("STRUCTURE", new ConfigBuilder<>(new StructureFactory(), StructureTemplate::new, TerraStructure.class, StructureRegistry::new));
add("TREE", new ConfigBuilder<>(new TreeFactory(), TreeTemplate::new, Tree.class, TreeRegistry::new));
add("BIOME", new ConfigBuilder<>(new BiomeFactory(pack), () -> new BiomeTemplate(pack, main), BiomeBuilder.class, BiomeRegistry::new));
add("PACK", new PackBuilder());
}
@Override
protected boolean add(String identifier, Entry<ConfigType<?, ?>> value) {
callback.accept(identifier, value.getValue());
return super.add(identifier, value);
}
private static final class PackBuilder implements ConfigType<ConfigTemplate, ConfigPack> {
@Override
public ConfigTemplate getTemplate(ConfigPack pack, TerraPlugin main) {
return new ConfigTemplate() {
};
}
@Override
public void callback(ConfigPack pack, TerraPlugin main, ConfigTemplate loadedConfig) {
}
@Override
public Class<ConfigPack> getTypeClass() {
return ConfigPack.class;
}
@Override
public Supplier<OpenRegistry<ConfigPack>> registrySupplier() {
return OpenRegistry::new;
}
}
private static final class ConfigBuilder<T extends AbstractableTemplate, O> implements ConfigType<T, O> {
private final ConfigFactory<T, O> factory;
private final Supplier<T> provider;
private final Class<O> clazz;
private final Supplier<OpenRegistry<O>> registrySupplier;
private ConfigBuilder(ConfigFactory<T, O> factory, Supplier<T> provider, Class<O> clazz, Supplier<OpenRegistry<O>> registrySupplier) {
this.factory = factory;
this.provider = provider;
this.clazz = clazz;
this.registrySupplier = registrySupplier;
}
@Override
public T getTemplate(ConfigPack pack, TerraPlugin main) {
return provider.get();
}
@SuppressWarnings("deprecation")
@Override
public void callback(ConfigPack pack, TerraPlugin main, T loadedConfig) throws LoadException {
pack.getRegistry(clazz).addUnchecked(loadedConfig.getID(), factory.build(loadedConfig, main));
}
@Override
public Class<O> getTypeClass() {
return clazz;
}
@Override
public Supplier<OpenRegistry<O>> registrySupplier() {
return registrySupplier;
}
}
}
@@ -57,7 +57,9 @@ public class FloraRegistry extends OpenRegistry<Flora> {
private void addItem(String id, Callable<ConstantFlora> flora) { private void addItem(String id, Callable<ConstantFlora> flora) {
try { try {
add(id, flora.call()); Entry<Flora> entry = new Entry<>(flora.call());
entry.getValue(); // Mark as not dead.
add(id, entry);
} catch(Exception e) { } catch(Exception e) {
main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage()); main.logger().warning("Failed to load Flora item: " + id + ": " + e.getMessage());
} }
@@ -1,6 +1,5 @@
package com.dfsek.terra.registry.config; package com.dfsek.terra.registry.config;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.math.noise.samplers.noise.random.GaussianNoiseSampler; import com.dfsek.terra.api.math.noise.samplers.noise.random.GaussianNoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler; import com.dfsek.terra.api.math.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2SSampler; import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2SSampler;
@@ -9,7 +8,7 @@ import com.dfsek.terra.api.math.noise.samplers.noise.simplex.PerlinSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.SimplexSampler; import com.dfsek.terra.api.math.noise.samplers.noise.simplex.SimplexSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.value.ValueCubicSampler; import com.dfsek.terra.api.math.noise.samplers.noise.value.ValueCubicSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.value.ValueSampler; import com.dfsek.terra.api.math.noise.samplers.noise.value.ValueSampler;
import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.util.seeded.NoiseProvider;
import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate;
import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate;
import com.dfsek.terra.config.loaders.config.sampler.templates.KernelTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.KernelTemplate;
@@ -26,9 +25,7 @@ import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.Linear
import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.normalizer.NormalNormalizerTemplate;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
import java.util.function.Supplier; public class NoiseRegistry extends OpenRegistry<NoiseProvider> {
public class NoiseRegistry extends OpenRegistry<Supplier<ObjectTemplate<NoiseSeeded>>> {
public NoiseRegistry() { public NoiseRegistry() {
add("LINEAR", LinearNormalizerTemplate::new); add("LINEAR", LinearNormalizerTemplate::new);
add("NORMAL", NormalNormalizerTemplate::new); add("NORMAL", NormalNormalizerTemplate::new);
@@ -1,22 +1,21 @@
package com.dfsek.terra.registry.config; package com.dfsek.terra.registry.config;
import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.SinglePalette; import com.dfsek.terra.api.world.palette.SinglePalette;
import com.dfsek.terra.registry.OpenRegistry; import com.dfsek.terra.registry.OpenRegistry;
public class PaletteRegistry extends OpenRegistry<Palette<BlockData>> { public class PaletteRegistry extends OpenRegistry<Palette> {
private final TerraPlugin main; private final TerraPlugin main;
public PaletteRegistry(TerraPlugin main) { public PaletteRegistry(TerraPlugin main) {
this.main = main; this.main = main;
} }
@Override @Override
public Palette<BlockData> get(String identifier) { public Palette get(String identifier) {
if(identifier.startsWith("BLOCK:")) if(identifier.startsWith("BLOCK:"))
return new SinglePalette<>(main.getWorldHandle().createBlockData(identifier.substring(6))); // Return single palette for BLOCK: shortcut. return new SinglePalette(main.getWorldHandle().createBlockData(identifier.substring(6))); // Return single palette for BLOCK: shortcut.
return super.get(identifier); return super.get(identifier);
} }
} }
@@ -75,7 +75,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 palette = biome.getGenerator(world).getPalette(y);
Sampler sampler = config.getSamplerCache().get(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);
@@ -1,7 +1,6 @@
package com.dfsek.terra.world.generation; package com.dfsek.terra.world.generation;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.world.biome.Generator; import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.palette.Palette; import com.dfsek.terra.api.world.palette.Palette;
import com.dfsek.terra.api.world.palette.holder.PaletteHolder; import com.dfsek.terra.api.world.palette.holder.PaletteHolder;
@@ -67,7 +66,7 @@ public class WorldGenerator implements Generator {
* @return BlockPalette - The biome's palette. * @return BlockPalette - The biome's palette.
*/ */
@Override @Override
public Palette<BlockData> getPalette(int y) { public Palette getPalette(int y) {
return palettes.getPalette(y); return palettes.getPalette(y);
} }
@@ -86,7 +85,7 @@ public class WorldGenerator implements Generator {
return blendStep; return blendStep;
} }
public Palette<BlockData> getSlantPalette(int y) { public Palette getSlantPalette(int y) {
return slantPalettes.getPalette(y); return slantPalettes.getPalette(y);
} }
} }
@@ -112,7 +112,7 @@ public class DefaultChunkGenerator2D implements TerraChunkGenerator {
TerraBiome b = grid.getBiome(xOrig + x, zOrig + z); TerraBiome b = grid.getBiome(xOrig + x, zOrig + z);
BiomeTemplate c = ((UserDefinedBiome) b).getConfig(); BiomeTemplate c = ((UserDefinedBiome) b).getConfig();
Palette<BlockData> seaPalette = c.getOceanPalette(); Palette seaPalette = c.getOceanPalette();
int height = FastMath.min((int) sampler.sample(x, 0, z), world.getMaxHeight() - 1); int height = FastMath.min((int) sampler.sample(x, 0, z), world.getMaxHeight() - 1);
@@ -45,7 +45,7 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
private final ConfigPack configPack; private final ConfigPack configPack;
private final TerraPlugin main; private final TerraPlugin main;
private final BlockType water; private final BlockType water;
private final SinglePalette<BlockData> blank; private final SinglePalette blank;
private final List<TerraBlockPopulator> blockPopulators = new ArrayList<>(); private final List<TerraBlockPopulator> blockPopulators = new ArrayList<>();
private final Carver carver; private final Carver carver;
@@ -63,7 +63,7 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
carver = new NoiseCarver(new Range(0, 255), main.getWorldHandle().createBlockData("minecraft:air"), main); carver = new NoiseCarver(new Range(0, 255), main.getWorldHandle().createBlockData("minecraft:air"), main);
water = main.getWorldHandle().createBlockData("minecraft:water").getBlockType(); water = main.getWorldHandle().createBlockData("minecraft:water").getBlockType();
blank = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:air")); blank = new SinglePalette(main.getWorldHandle().createBlockData("minecraft:air"));
} }
@Override @Override
@@ -124,7 +124,7 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
BiomeTemplate c = ((UserDefinedBiome) b).getConfig(); BiomeTemplate c = ((UserDefinedBiome) b).getConfig();
int sea = c.getSeaLevel(); int sea = c.getSeaLevel();
Palette<BlockData> seaPalette = c.getOceanPalette(); Palette seaPalette = c.getOceanPalette();
boolean justSet = false; boolean justSet = false;
BlockData data = null; BlockData data = null;
@@ -162,11 +162,11 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
} }
} }
private void prepareBlockPartFloor(BlockData down, BlockData orig, ChunkData chunk, Vector3 block, Map<BlockType, Palette<BlockData>> slabs, private void prepareBlockPartFloor(BlockData down, BlockData orig, ChunkData chunk, Vector3 block, Map<BlockType, Palette> slabs,
Map<BlockType, Palette<BlockData>> stairs, double thresh, Sampler sampler) { Map<BlockType, Palette> stairs, double thresh, Sampler sampler) {
if(sampler.sample(block.getX(), block.getY() - 0.4, block.getZ()) > thresh) { if(sampler.sample(block.getX(), block.getY() - 0.4, block.getZ()) > thresh) {
if(stairs != null) { if(stairs != null) {
Palette<BlockData> stairPalette = stairs.get(down.getBlockType()); Palette stairPalette = stairs.get(down.getBlockType());
if(stairPalette != null) { if(stairPalette != null) {
BlockData stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone(); BlockData stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone();
if(stair instanceof Stairs) { if(stair instanceof Stairs) {
@@ -183,11 +183,11 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
} }
} }
private void prepareBlockPartCeiling(BlockData up, BlockData orig, ChunkData chunk, Vector3 block, Map<BlockType, Palette<BlockData>> slabs, private void prepareBlockPartCeiling(BlockData up, BlockData orig, ChunkData chunk, Vector3 block, Map<BlockType, Palette> slabs,
Map<BlockType, Palette<BlockData>> stairs, double thresh, Sampler sampler) { Map<BlockType, Palette> stairs, double thresh, Sampler sampler) {
if(sampler.sample(block.getX(), block.getY() + 0.4, block.getZ()) > thresh) { if(sampler.sample(block.getX(), block.getY() + 0.4, block.getZ()) > thresh) {
if(stairs != null) { if(stairs != null) {
Palette<BlockData> stairPalette = stairs.get(up.getBlockType()); Palette stairPalette = stairs.get(up.getBlockType());
if(stairPalette != null) { if(stairPalette != null) {
BlockData stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone(); BlockData stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone();
if(stair instanceof Stairs) { if(stair instanceof Stairs) {
@@ -22,7 +22,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TerraFlora implements Flora { public class TerraFlora implements Flora {
private final Palette<BlockData> floraPalette; private final Palette floraPalette;
private final boolean physics; private final boolean physics;
private final boolean ceiling; private final boolean ceiling;
@@ -43,7 +43,7 @@ public class TerraFlora implements Flora {
private final TerraPlugin main; private final TerraPlugin main;
public TerraFlora(Palette<BlockData> floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, MaterialSet testRotation, int maxPlacements, Search search, boolean spawnBlacklist, int irrigableOffset, TerraPlugin main) { public TerraFlora(Palette floraPalette, boolean physics, boolean ceiling, MaterialSet irrigable, MaterialSet spawnable, MaterialSet replaceable, MaterialSet testRotation, int maxPlacements, Search search, boolean spawnBlacklist, int irrigableOffset, TerraPlugin main) {
this.floraPalette = floraPalette; this.floraPalette = floraPalette;
this.physics = physics; this.physics = physics;
this.testRotation = testRotation; this.testRotation = testRotation;
@@ -1,352 +0,0 @@
package biome;
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeRegistry;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.event.EventManager;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.registry.LockedRegistry;
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
import com.dfsek.terra.api.util.logging.DebugLogger;
import com.dfsek.terra.api.util.logging.JavaLogger;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.Generator;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.fileloaders.FolderLoader;
import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
import com.dfsek.terra.config.loaders.config.biome.BiomeProviderBuilderLoader;
import com.dfsek.terra.config.loaders.config.biome.templates.provider.BiomePipelineTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.provider.ImageProviderTemplate;
import com.dfsek.terra.config.loaders.config.biome.templates.provider.SingleBiomeProviderTemplate;
import com.dfsek.terra.config.loaders.config.sampler.NoiseSamplerBuilderLoader;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.AbstractableTemplate;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.registry.config.BiomeRegistry;
import com.dfsek.terra.registry.config.NoiseRegistry;
import com.dfsek.terra.world.TerraWorld;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Logger;
public class DistributionTest {
private static final TerraPlugin MAIN = new TerraPlugin() {
@Override
public WorldHandle getWorldHandle() {
return null;
}
@Override
public TerraWorld getWorld(World world) {
return null;
}
@Override
public com.dfsek.terra.api.util.logging.Logger logger() {
return new JavaLogger(Logger.getLogger("Terra"));
}
@Override
public PluginConfig getTerraConfig() {
return new PluginConfig();
}
@Override
public File getDataFolder() {
return null;
}
@Override
public boolean isDebug() {
return false;
}
@Override
public Language getLanguage() {
return null;
}
@Override
public CheckedRegistry<ConfigPack> getConfigRegistry() {
return null;
}
@Override
public LockedRegistry<TerraAddon> getAddons() {
return null;
}
@Override
public boolean reload() {
return true;
}
@Override
public ItemHandle getItemHandle() {
return null;
}
@Override
public void saveDefaultConfig() {
}
@Override
public String platformName() {
return null;
}
@Override
public DebugLogger getDebugLogger() {
return new DebugLogger(new JavaLogger(Logger.getLogger("Terra")));
}
@Override
public EventManager getEventManager() {
return null;
}
@Override
public void register(TypeRegistry registry) {
}
};
private static BiomeProvider getProvider(long seed) throws ConfigException, IOException {
System.out.println(seed);
File pack = new File("/home/dfsek/Documents/Terra/platforms/bukkit/target/server/plugins/Terra/packs/default/");
FolderLoader folderLoader = new FolderLoader(pack.toPath());
AbstractConfigLoader loader = new AbstractConfigLoader();
new GenericLoaders(MAIN).register(loader);
BiomeRegistry biomeRegistry = new BiomeRegistry();
folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), MAIN));
BiomeProviderTemplate template = new BiomeProviderTemplate();
ConfigLoader pipeLoader = new ConfigLoader()
.registerLoader(BiomeProvider.BiomeProviderBuilder.class, new BiomeProviderBuilderLoader())
.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader())
.registerLoader(BiomeBuilder.class, biomeRegistry)
.registerLoader(BufferedImage.class, new BufferedImageLoader(folderLoader))
.registerLoader(SingleBiomeProviderTemplate.class, SingleBiomeProviderTemplate::new)
.registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(MAIN))
.registerLoader(ImageProviderTemplate.class, () -> new ImageProviderTemplate(biomeRegistry));
new GenericLoaders(MAIN).register(pipeLoader);
pipeLoader.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(new NoiseRegistry()));
pipeLoader.load(template, folderLoader.get("pack.yml"));
return template.getBiomeProviderBuilder().build(seed);
}
public static void main(String... args) throws ConfigException, IOException {
JFrame testFrame = new JFrame("Biome Viewer");
final BiomeProvider[] provider = {getProvider(2403)};
int size = 1024;
final BufferedImage[] image = {new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB)};
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
image[0].setRGB(x, z, provider[0].getBiome(x, z).getColor());
}
}
JLabel img = new JLabel(new ImageIcon(image[0]));
testFrame.add(img);
testFrame.pack();
img.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
BufferedImage newImage = deepCopy(image[0]);
Graphics graphics = newImage.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 512, 24);
graphics.setColor(Color.BLACK);
graphics.setFont(new Font("Monospace", Font.BOLD, 20));
graphics.drawString(provider[0].getBiome(e.getX(), e.getY()).toString(), 0, 20);
graphics.setColor(Color.WHITE);
graphics.fillOval(e.getX() - 2, e.getY() - 2, 12, 12);
graphics.setColor(Color.BLACK);
graphics.fillOval(e.getX(), e.getY(), 8, 8);
img.setIcon(new ImageIcon(newImage));
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
testFrame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == 's') {
long l = System.nanoTime();
try {
provider[0] = getProvider(ThreadLocalRandom.current().nextLong());
} catch(ConfigException | IOException configException) {
configException.printStackTrace();
}
image[0] = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
image[0].setRGB(x, z, provider[0].getBiome(x, z).getColor());
}
}
long n = System.nanoTime();
double t = n - l;
System.out.println("Time: " + t / 1000000 + "ms");
img.setIcon(new ImageIcon(image[0]));
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
testFrame.setResizable(false);
testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
testFrame.setVisible(true);
}
private static BufferedImage deepCopy(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
private static final class BiomeProviderTemplate implements ConfigTemplate {
@Value("biomes")
BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
public BiomeProvider.BiomeProviderBuilder getBiomeProviderBuilder() {
return biomeProviderBuilder;
}
}
private static final class TestBiome extends AbstractableTemplate implements TerraBiome, ValidatedConfigTemplate, BiomeBuilder {
@Value("color")
@Default
@Abstractable
private int color;
@Value("tags")
@Abstractable
@Default
private Set<String> tags = new HashSet<>();
@Value("id")
private String id;
@Override
public ProbabilityCollection<Biome> getVanillaBiomes() {
return null;
}
@Override
public BiomeTemplate getTemplate() {
return null;
}
@Override
public Generator getGenerator(World w) {
return null;
}
@Override
public int getColor() {
return color;
}
@Override
public Set<String> getTags() {
return tags;
}
@Override
public boolean validate() {
color += (255 << 24); // Alpha adjustment
tags.add("BIOME:" + id);
return true;
}
@Override
public String getID() {
return id;
}
@Override
public String toString() {
return id;
}
@Override
public TestBiome apply(Long aLong) {
return this;
}
}
}
-218
View File
@@ -1,218 +0,0 @@
package biome;
import com.dfsek.tectonic.abstraction.AbstractConfigLoader;
import com.dfsek.tectonic.annotations.Abstractable;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ConfigException;
import com.dfsek.terra.api.platform.world.Biome;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.collections.ProbabilityCollection;
import com.dfsek.terra.api.world.biome.Generator;
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.ImageBiomeProvider;
import com.dfsek.terra.config.fileloaders.FolderLoader;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.AbstractableTemplate;
import com.dfsek.terra.registry.OpenRegistry;
import org.junit.jupiter.api.Test;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
public class ImageTest {
private static ImageBiomeProvider getProvider(long seed) throws ConfigException, IOException {
System.out.println(seed);
File pack = new File("/home/dfsek/Documents/Terra/platforms/bukkit/target/server/plugins/Terra/packs/default/");
FolderLoader folderLoader = new FolderLoader(pack.toPath());
AbstractConfigLoader loader = new AbstractConfigLoader();
OpenRegistry<TerraBiome> biomeRegistry = new OpenRegistry<TerraBiome>() {
};
folderLoader.open("biomes", ".yml").then(inputStreams -> ConfigPack.buildAll((template, main) -> template, biomeRegistry, loader.load(inputStreams, TestBiome::new), null));
return new ImageBiomeProvider(biomeRegistry.entries(), ImageIO.read(ImageTest.class.getResourceAsStream("/map.jpg")), 1, ImageBiomeProvider.Align.CENTER);
}
@Test
public static void main(String... args) throws ConfigException, IOException {
JFrame testFrame = new JFrame("Biome Viewer");
final BiomeProvider[] provider = {getProvider(2403)};
int size = 1024;
final BufferedImage[] image = {new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB)};
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
image[0].setRGB(x, z, provider[0].getBiome(x, z).getColor());
}
}
JLabel img = new JLabel(new ImageIcon(image[0]));
testFrame.add(img);
testFrame.pack();
img.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
BufferedImage newImage = deepCopy(image[0]);
Graphics graphics = newImage.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 512, 24);
graphics.setColor(Color.BLACK);
graphics.setFont(new Font("Monospace", Font.BOLD, 20));
graphics.drawString(provider[0].getBiome(e.getX(), e.getY()).toString(), 0, 20);
graphics.setColor(Color.WHITE);
graphics.fillOval(e.getX() - 2, e.getY() - 2, 12, 12);
graphics.setColor(Color.BLACK);
graphics.fillOval(e.getX(), e.getY(), 8, 8);
img.setIcon(new ImageIcon(newImage));
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
testFrame.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == 's') {
try {
provider[0] = getProvider(ThreadLocalRandom.current().nextLong());
} catch(ConfigException | IOException configException) {
configException.printStackTrace();
}
image[0] = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
image[0].setRGB(x, z, provider[0].getBiome(x, z).getColor());
}
}
img.setIcon(new ImageIcon(image[0]));
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
testFrame.setResizable(false);
testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
testFrame.setVisible(true);
}
private static BufferedImage deepCopy(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
private static final class BiomeProviderTemplate implements ConfigTemplate {
@Value("biome-pipeline")
BiomeProvider.BiomeProviderBuilder biomeProviderBuilder;
public BiomeProvider.BiomeProviderBuilder getBiomeProviderBuilder() {
return biomeProviderBuilder;
}
}
private static final class TestBiome extends AbstractableTemplate implements TerraBiome, ValidatedConfigTemplate {
@Value("color")
@Default
@Abstractable
private int color;
@Value("tags")
@Abstractable
@Default
private Set<String> tags = new HashSet<>();
@Value("id")
private String id;
@Override
public ProbabilityCollection<Biome> getVanillaBiomes() {
return null;
}
@Override
public Generator getGenerator(World w) {
return null;
}
@Override
public int getColor() {
return color;
}
@Override
public Set<String> getTags() {
return tags;
}
@Override
public boolean validate() {
color += (255 << 24); // Alpha adjustment
tags.add("BIOME:" + id);
return true;
}
@Override
public String getID() {
return id;
}
@Override
public String toString() {
return id;
}
}
}
+7 -13
View File
@@ -16,19 +16,12 @@ configureCommon()
group = "com.dfsek.terra.bukkit" group = "com.dfsek.terra.bukkit"
val mcVersion = "1.16.5" val mcVersion = "1.16.5"
val testDir = "target/server/" val testDir = "target/server"
val testMem = "3G" val testMem = "3G"
val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/" val paperURL = "https://papermc.io/api/v1/paper/%version%/latest/download/"
val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar" val purpurURL = "https://ci.pl3x.net/job/Purpur/lastSuccessfulBuild/artifact/final/purpurclip.jar"
repositories {
mavenCentral()
maven { url = uri("http://maven.enginehub.org/repo/") }
maven { url = uri("https://repo.codemc.org/repository/maven-public") }
maven { url = uri("https://papermc.io/repo/repository/maven-public/") }
}
dependencies { dependencies {
"shadedApi"(project(":common")) "shadedApi"(project(":common"))
@@ -39,17 +32,17 @@ dependencies {
"compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT") "compileOnly"("com.sk89q.worldedit:worldedit-bukkit:7.2.0-SNAPSHOT")
"shadedImplementation"("com.google.guava:guava:30.0-jre") "shadedApi"("com.google.guava:guava:30.0-jre")
} }
val aikarsFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200", val jvmFlags = listOf("-XX:+UseG1GC", "-XX:+ParallelRefProcEnabled", "-XX:MaxGCPauseMillis=200",
"-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch", "-XX:+UnlockExperimentalVMOptions", "-XX:+DisableExplicitGC", "-XX:+AlwaysPreTouch",
"-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M", "-XX:G1NewSizePercent=30", "-XX:G1MaxNewSizePercent=40", "-XX:G1HeapRegionSize=8M",
"-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4", "-XX:G1ReservePercent=20", "-XX:G1HeapWastePercent=5", "-XX:G1MixedGCCountTarget=4",
"-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90", "-XX:InitiatingHeapOccupancyPercent=15", "-XX:G1MixedGCLiveThresholdPercent=90",
"-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem", "-XX:G1RSetUpdatingPauseTimePercent=5", "-XX:SurvivorRatio=32", "-XX:+PerfDisableSharedMem",
"-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs", "-XX:MaxTenuringThreshold=1", "-Dusing.aikars.flags=https://mcflags.emc.gs",
"-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear") "-Daikars.new.flags=true", "-DIReallyKnowWhatIAmDoingISwear", "-javaagent:paperclip.jar")
fun downloadPaperclip(url: String, dir: String) { fun downloadPaperclip(url: String, dir: String) {
val clip = URL(url.replace("%version%", mcVersion)) val clip = URL(url.replace("%version%", mcVersion))
@@ -160,7 +153,7 @@ task<JavaExec>(name = "runPaper") {
} }
main = "io.papermc.paperclip.Paperclip" main = "io.papermc.paperclip.Paperclip"
jvmArgs = aikarsFlags jvmArgs = jvmFlags
maxHeapSize = testMem maxHeapSize = testMem
minHeapSize = testMem minHeapSize = testMem
//args = listOf("nogui") //args = listOf("nogui")
@@ -178,7 +171,7 @@ task<JavaExec>(name = "runPurpur") {
} }
main = "io.papermc.paperclip.Paperclip" main = "io.papermc.paperclip.Paperclip"
jvmArgs = aikarsFlags jvmArgs = jvmFlags
maxHeapSize = testMem maxHeapSize = testMem
minHeapSize = testMem minHeapSize = testMem
//args = listOf("nogui") //args = listOf("nogui")
@@ -189,6 +182,7 @@ task<JavaExec>(name = "runPurpur") {
tasks.named<ShadowJar>("shadowJar") { tasks.named<ShadowJar>("shadowJar") {
relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats") relocate("org.bstats.bukkit", "com.dfsek.terra.lib.bstats")
relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib") relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib")
relocate("com.google.common", "com.dfsek.terra.lib.google.common")
} }
publishing { publishing {
@@ -28,6 +28,6 @@ public class BukkitWorldHandle implements WorldHandle {
@Override @Override
public Pair<Location, Location> getSelectedLocation(Player player) { public Pair<Location, Location> getSelectedLocation(Player player) {
org.bukkit.Location[] locations = WorldEditUtil.getSelectionLocations(BukkitAdapter.adapt(player)); org.bukkit.Location[] locations = WorldEditUtil.getSelectionLocations(BukkitAdapter.adapt(player));
return new Pair<>(BukkitAdapter.adapt(locations[0]), BukkitAdapter.adapt(locations[1])); return Pair.of(BukkitAdapter.adapt(locations[0]), BukkitAdapter.adapt(locations[1]));
} }
} }
@@ -52,7 +52,7 @@ public class CommonListener implements Listener {
Block block = e.getLocation().getBlock(); Block block = e.getLocation().getBlock();
BlockData data = block.getBlockData(); BlockData data = block.getBlockData();
block.setType(Material.AIR); block.setType(Material.AIR);
Tree tree = c.getTreeRegistry().get(TREE_TYPE_STRING_TRANSFORMER.translate(e.getSpecies())); Tree tree = c.getRegistry(Tree.class).get(TREE_TYPE_STRING_TRANSFORMER.translate(e.getSpecies()));
org.bukkit.Location location = e.getLocation(); org.bukkit.Location location = e.getLocation();
if(!tree.plant(new Location(bukkit, location.getX(), location.getY(), location.getZ()), new FastRandom())) block.setBlockData(data); if(!tree.plant(new Location(bukkit, location.getX(), location.getY(), location.getZ()), new FastRandom())) block.setBlockData(data);
} }
@@ -23,7 +23,7 @@ public class PaperListener implements Listener {
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())); TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getWorld()));
TerraStructure config = tw.getConfig().getStructureRegistry().get(tw.getConfig().getTemplate().getLocatable().get(name)); TerraStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(tw.getConfig().getTemplate().getLocatable().get(name));
if(config != null) { if(config != null) {
AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getOrigin()), 0, 500, location -> { AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getOrigin()), 0, 500, location -> {
if(location != null) if(location != null)
@@ -37,7 +37,7 @@ public class SpigotListener implements Listener {
if(!TerraWorld.isTerraWorld(BukkitAdapter.adapt(e.getEntity().getWorld()))) return; if(!TerraWorld.isTerraWorld(BukkitAdapter.adapt(e.getEntity().getWorld()))) return;
TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getEntity().getWorld())); TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getEntity().getWorld()));
EnderSignal signal = (EnderSignal) entity; EnderSignal signal = (EnderSignal) entity;
TerraStructure config = tw.getConfig().getStructureRegistry().get(tw.getConfig().getTemplate().getLocatable().get("STRONGHOLD")); TerraStructure config = tw.getConfig().getRegistry(TerraStructure.class).get(tw.getConfig().getTemplate().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()), 0, 500, location -> { AsyncStructureFinder finder = new AsyncStructureFinder(tw.getBiomeProvider(), config, BukkitAdapter.adapt(e.getLocation()), 0, 500, location -> {
@@ -5,6 +5,7 @@ import com.dfsek.terra.api.event.EventListener;
import com.dfsek.terra.api.event.annotations.Global; import com.dfsek.terra.api.event.annotations.Global;
import com.dfsek.terra.api.event.annotations.Priority; import com.dfsek.terra.api.event.annotations.Priority;
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.bukkit.world.BukkitTree; import com.dfsek.terra.bukkit.world.BukkitTree;
import com.dfsek.terra.registry.exception.DuplicateEntryException; import com.dfsek.terra.registry.exception.DuplicateEntryException;
@@ -22,7 +23,9 @@ public class TerraListener implements EventListener {
public void injectTrees(ConfigPackPreLoadEvent event) { public void injectTrees(ConfigPackPreLoadEvent event) {
for(TreeType value : TreeType.values()) { for(TreeType value : TreeType.values()) {
try { try {
event.getPack().getTreeRegistry().add(BukkitAdapter.TREE_TRANSFORMER.translate(value), new BukkitTree(value, main)); String id = BukkitAdapter.TREE_TRANSFORMER.translate(value);
event.getPack().getRegistry(Tree.class).add(id, new BukkitTree(value, main));
event.getPack().getRegistry(Tree.class).get(id); // Platform trees should never be marked "dead"
} catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing. } catch(DuplicateEntryException ignore) { // If another addon has already registered trees, do nothing.
} }
} }
+25 -7
View File
@@ -6,6 +6,7 @@ import net.fabricmc.loom.task.RemapJarTask
plugins { plugins {
`java-library` `java-library`
`maven-publish`
id("fabric-loom").version("0.6-SNAPSHOT") id("fabric-loom").version("0.6-SNAPSHOT")
id("com.modrinth.minotaur").version("1.1.0") id("com.modrinth.minotaur").version("1.1.0")
} }
@@ -21,8 +22,6 @@ group = "com.dfsek.terra.fabric"
dependencies { dependencies {
"shadedApi"(project(":common")) "shadedApi"(project(":common"))
"shadedImplementation"("org.yaml:snakeyaml:1.27")
"shadedImplementation"("com.googlecode.json-simple:json-simple:1.1.1")
"minecraft"("com.mojang:minecraft:1.16.5") "minecraft"("com.mojang:minecraft:1.16.5")
"mappings"("net.fabricmc:yarn:1.16.5+build.5:v2") "mappings"("net.fabricmc:yarn:1.16.5+build.5:v2")
@@ -31,11 +30,6 @@ dependencies {
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16") "modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
} }
tasks.named<ShadowJar>("shadowJar") {
relocate("org.json", "com.dfsek.terra.lib.json")
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
}
configure<LoomGradleExtension> { configure<LoomGradleExtension> {
accessWidener("src/main/resources/terra.accesswidener") accessWidener("src/main/resources/terra.accesswidener")
@@ -63,4 +57,28 @@ tasks.register<TaskModrinthUpload>("publishModrinth") {
addGameVersion("1.16.4") addGameVersion("1.16.4")
addGameVersion("1.16.5") addGameVersion("1.16.5")
addLoader("fabric") addLoader("fabric")
}
publishing {
publications {
create<MavenPublication>("mavenJava") {
artifact(tasks["sourcesJar"])
artifact(tasks["jar"])
}
}
repositories {
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
maven(mavenUrl) {
val mavenUsername: String? by project
val mavenPassword: String? by project
if (mavenUsername != null && mavenPassword != null) {
credentials {
username = mavenUsername
password = mavenPassword
}
}
}
}
} }
@@ -311,7 +311,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "flora_populator")); RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "flora_populator"));
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), POPULATOR_CONFIGURED_FEATURE); Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), POPULATOR_CONFIGURED_FEATURE);
registry.forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, id)), createBiome(biome)))); // Register all Terra biomes. registry.forEach(pack -> pack.getRegistry(BiomeBuilder.class).forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, id)), createBiome(biome)))); // Register all Terra biomes.
Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC); Registry.register(Registry.CHUNK_GENERATOR, new Identifier("terra:terra"), FabricChunkGeneratorWrapper.CODEC);
Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC); Registry.register(Registry.BIOME_SOURCE, new Identifier("terra:terra"), TerraBiomeSource.CODEC);
@@ -408,7 +408,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
@Priority(Priority.LOWEST) @Priority(Priority.LOWEST)
@Global @Global
public void injectTrees(ConfigPackPreLoadEvent event) { public void injectTrees(ConfigPackPreLoadEvent event) {
CheckedRegistry<Tree> treeRegistry = event.getPack().getTreeRegistry(); CheckedRegistry<Tree> treeRegistry = event.getPack().getRegistry(Tree.class);
injectTree(treeRegistry, "BROWN_MUSHROOM", ConfiguredFeatures.HUGE_BROWN_MUSHROOM); injectTree(treeRegistry, "BROWN_MUSHROOM", ConfiguredFeatures.HUGE_BROWN_MUSHROOM);
injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.HUGE_RED_MUSHROOM); injectTree(treeRegistry, "RED_MUSHROOM", ConfiguredFeatures.HUGE_RED_MUSHROOM);
injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE); injectTree(treeRegistry, "JUNGLE", ConfiguredFeatures.MEGA_JUNGLE_TREE);
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.fabric.world.FabricAdapter; import com.dfsek.terra.fabric.world.FabricAdapter;
import com.dfsek.terra.fabric.world.block.state.FabricBlockState; import com.dfsek.terra.fabric.world.block.state.FabricBlockState;
import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess; import com.dfsek.terra.fabric.world.handles.world.FabricWorldAccess;
import net.minecraft.block.FluidBlock;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
@@ -21,7 +22,10 @@ public class FabricBlock implements Block {
@Override @Override
public void setBlockData(BlockData data, boolean physics) { public void setBlockData(BlockData data, boolean physics) {
delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042, 0); delegate.worldAccess.setBlockState(delegate.position, ((FabricBlockData) data).getHandle(), physics ? 3 : 1042);
if(physics && ((FabricBlockData) data).getHandle().getBlock() instanceof FluidBlock) {
delegate.worldAccess.getFluidTickScheduler().schedule(delegate.position, ((FluidBlock) ((FabricBlockData) data).getHandle().getBlock()).getFluidState(((FabricBlockData) data).getHandle()).getFluid(), 0);
}
} }
@Override @Override