implementation compiles now

This commit is contained in:
dfsek
2021-07-04 19:59:46 -07:00
parent e9dc7d3db6
commit 54f4722297
26 changed files with 47 additions and 303 deletions
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.biome;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.util.ProbabilityCollection;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
import com.dfsek.terra.addons.biome.pipeline.source.RandomSource;
import com.dfsek.terra.api.util.seeded.BiomeBuilder;
public class NoiseSourceTemplate extends SourceTemplate {
@Value("noise")
private NoiseSeeded noise;
@Value("biomes")
private ProbabilityCollection<BiomeBuilder> biomes;
@Override
public BiomeSource apply(Long seed) {
return new RandomSource(biomes.map((biome) -> biome.apply(seed), false), noise.apply(seed));
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.biome;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.math.range.ConstantRange;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.addons.ore.ores.OreConfig;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class OreConfigLoader implements TypeLoader<OreConfig> {
@Override
public OreConfig load(Type type, Object o, ConfigLoader configLoader) {
Map<String, Integer> map = (Map<String, Integer>) o;
Range amount = new ConstantRange(map.get("min"), map.get("max"));
Range height = new ConstantRange(map.get("min-height"), map.get("max-height"));
return new OreConfig(amount, height);
}
}
@@ -0,0 +1,26 @@
package com.dfsek.terra.addons.biome;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.addons.ore.ores.Ore;
import com.dfsek.terra.addons.ore.ores.OreConfig;
import com.dfsek.terra.addons.ore.ores.OreHolder;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class OreHolderLoader implements TypeLoader<OreHolder> {
@Override
public OreHolder load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
OreHolder holder = new OreHolder();
Map<String, Object> map = (Map<String, Object>) o;
for(Map.Entry<String, Object> entry : map.entrySet()) {
holder.add(configLoader.loadClass(Ore.class, entry.getKey()), configLoader.loadClass(OreConfig.class, entry.getValue()), entry.getKey());
}
return holder;
}
}
@@ -0,0 +1,11 @@
package com.dfsek.terra.addons.biome;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.util.seeded.SourceSeeded;
public abstract class SourceTemplate implements ObjectTemplate<SourceSeeded>, SourceSeeded {
@Override
public SourceSeeded get() {
return this;
}
}
@@ -0,0 +1,45 @@
package com.dfsek.terra.addons.biome.command.biome;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Player;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
subcommands = {
@Subcommand(
value = "info",
aliases = {"i"},
clazz = BiomeInfoCommand.class
),
@Subcommand(
value = "locate",
aliases = {"l"},
clazz = BiomeLocateCommand.class
)
},
usage = "/terra biome"
)
@WorldCommand
@PlayerCommand
public class BiomeCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider();
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position());
LangUtil.send("command.biome.in", sender, biome.getID());
}
}
@@ -0,0 +1,56 @@
package com.dfsek.terra.addons.biome.command.biome;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.structure.ConfiguredStructure;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.population.items.TerraStructure;
import java.util.List;
@Command(
arguments = {
@Argument(
value = "biome",
tabCompleter = BiomeTabCompleter.class,
argumentParser = BiomeArgumentParser.class
)
}
)
public class BiomeInfoCommand implements CommandTemplate {
@ArgumentTarget("biome")
private TerraBiome biome;
@Override
public void execute(CommandSender sender) {
sender.sendMessage("Biome info for \"" + biome.getID() + "\".");
sender.sendMessage("Vanilla biome: " + biome.getVanillaBiomes());
if(biome instanceof UserDefinedBiome) {
BiomeTemplate bio = ((UserDefinedBiome) biome).getConfig();
if(bio.getExtended().size() == 0) {
sender.sendMessage("No Parent Biomes");
} else {
sender.sendMessage("------Parent Biomes-----");
bio.getExtended().forEach(id -> sender.sendMessage(" - " + id));
}
List<ConfiguredStructure> structureConfigs = bio.getStructures();
if(structureConfigs.size() == 0) {
sender.sendMessage("No Structures");
} else {
sender.sendMessage("-------Structures-------");
for(TerraStructure c : structureConfigs) {
sender.sendMessage(" - " + c.getTemplate().getID());
}
}
}
}
}
@@ -0,0 +1,77 @@
package com.dfsek.terra.addons.biome.command.biome;
import com.dfsek.terra.addons.biome.command.biome.arg.BiomeArgumentParser;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Player;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.locate.AsyncBiomeFinder;
import com.dfsek.terra.addons.biome.command.biome.tab.BiomeTabCompleter;
import com.dfsek.terra.config.lang.LangUtil;
import java.util.Locale;
@PlayerCommand
@WorldCommand
@Command(
arguments = {
@Argument(
value = "biome",
tabCompleter = BiomeTabCompleter.class,
argumentParser = BiomeArgumentParser.class
),
@Argument(
value = "radius",
required = false,
defaultValue = "1000",
argumentParser = IntegerArgumentParser.class
)
},
switches = {
@Switch(
value = "teleport",
aliases = {"t", "tp"}
)
}
)
public class BiomeLocateCommand implements CommandTemplate {
@ArgumentTarget("radius")
private Integer radius;
@ArgumentTarget("biome")
private TerraBiome biome;
@SwitchTarget("teleport")
private boolean teleport;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
new Thread(new AsyncBiomeFinder(main.getWorld(player.world()).getBiomeProvider(), biome, player.position().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), player.world(), 0, radius, location -> {
if(location != null) {
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.position().getY(), 0)).distance(player.position())));
if(teleport) {
main.runPossiblyUnsafeTask(() -> player.position(new Vector3(location.getX(), player.position().getY(), location.getZ())));
}
} else LangUtil.send("command.biome.unable-to-locate", sender);
}, main), "Biome Location Thread").start();
}
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.addons.biome.command.biome.arg;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Player;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class BiomeArgumentParser implements ArgumentParser<TerraBiome> {
@Inject
private TerraPlugin main;
@Override
public TerraBiome parse(CommandSender sender, String arg) {
Player player = (Player) sender;
return main.getWorld(player.world()).getConfig().getRegistry(TerraBiome.class).get(arg);
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.addons.biome.command.biome.tab;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.entity.CommandSender;
import com.dfsek.terra.api.entity.Player;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.world.biome.TerraBiome;
import java.util.List;
import java.util.stream.Collectors;
public class BiomeTabCompleter implements TabCompleter {
@Inject
private TerraPlugin main;
@Override
public List<String> complete(CommandSender sender) {
Player player = (Player) sender;
return main.getWorld(player.world()).getConfig().getRegistry(TerraBiome.class).entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
}
}
@@ -0,0 +1,26 @@
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.api.util.seeded.SourceSeeded;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
import com.dfsek.terra.config.loaders.config.biome.templates.source.NoiseSourceTemplate;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class SourceBuilderLoader implements TypeLoader<SourceSeeded> {
@Override
public SourceSeeded load(Type t, Object c, ConfigLoader loader) throws LoadException {
Map<String, Object> source = (Map<String, Object>) c;
BiomeSource.Type type = loader.loadClass(BiomeSource.Type.class, source.get("type"));
if(type == BiomeSource.Type.NOISE) {
return loader.loadClass(NoiseSourceTemplate.class, source);
}
throw new LoadException("No such loader type: " + type);
}
}
@@ -0,0 +1,20 @@
package structure;
import com.dfsek.terra.addons.structure.structures.tokenizer.Lookahead;
import org.junit.jupiter.api.Test;
import java.io.StringReader;
public class LookaheadTest {
@Test
public void lookahead() {
Lookahead lookahead = new Lookahead(new StringReader("Test string..."));
for(int i = 0; lookahead.next(i) != null; i++) {
System.out.print(lookahead.next(i).getCharacter());
}
while(lookahead.next(0) != null) {
System.out.print(lookahead.consume().getCharacter());
}
}
}
@@ -0,0 +1,88 @@
package structure;
import com.dfsek.terra.addons.structure.structures.parser.Parser;
import com.dfsek.terra.addons.structure.structures.parser.exceptions.ParseException;
import com.dfsek.terra.addons.structure.structures.parser.lang.Block;
import com.dfsek.terra.addons.structure.structures.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.structure.structures.parser.lang.Returnable;
import com.dfsek.terra.addons.structure.structures.parser.lang.functions.Function;
import com.dfsek.terra.addons.structure.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.addons.structure.structures.parser.lang.variables.Variable;
import com.dfsek.terra.addons.structure.structures.tokenizer.Position;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ParserTest {
@Test
public void parse() throws IOException, ParseException {
Parser parser = new Parser(IOUtils.toString(getClass().getResourceAsStream("/test.tesf"), Charset.defaultCharset()));
parser.registerFunction("test", new FunctionBuilder<Test1>() {
@Override
public Test1 build(List<Returnable<?>> argumentList, Position position) {
return new Test1(argumentList.get(0), argumentList.get(1), position);
}
@Override
public int argNumber() {
return 2;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
return Returnable.ReturnType.STRING;
case 1:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
});
long l = System.nanoTime();
Block block = parser.parse();
long t = System.nanoTime() - l;
System.out.println("Took " + (double) t / 1000000);
block.apply(null, new HashMap<>());
block.apply(null, new HashMap<>());
}
private static class Test1 implements Function<Void> {
private final Returnable<?> a;
private final Returnable<?> b;
private final Position position;
public Test1(Returnable<?> a, Returnable<?> b, Position position) {
this.a = a;
this.b = b;
this.position = position;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
System.out.println("string: " + a.apply(implementationArguments, variableMap) + ", double: " + b.apply(implementationArguments, variableMap));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
}
@@ -0,0 +1,34 @@
package com.dfsek.terra.addons.tree;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.tectonic.loading.ConfigLoader;
import com.dfsek.tectonic.loading.TypeLoader;
import com.dfsek.terra.addons.tree.tree.TreeLayer;
import com.dfsek.terra.api.util.ProbabilityCollection;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.api.world.Tree;
import com.dfsek.terra.config.loaders.Types;
import com.dfsek.terra.noise.samplers.noise.random.WhiteNoiseSampler;
import java.lang.reflect.Type;
import java.util.Map;
@SuppressWarnings("unchecked")
public class TreeLayerLoader implements TypeLoader<TreeLayer> {
@Override
public TreeLayer load(Type type, Object o, ConfigLoader configLoader) throws LoadException {
Map<String, Object> map = (Map<String, Object>) o;
double density = ((Number) map.get("density")).doubleValue();
Range range = configLoader.loadClass(Range.class, map.get("y"));
if(range == null) throw new LoadException("Tree range unspecified");
ProbabilityCollection<Tree> items = (ProbabilityCollection<Tree>) configLoader.loadType(Types.TREE_PROBABILITY_COLLECTION_TYPE, map.get("items"));
if(map.containsKey("distribution")) {
NoiseSeeded noise = configLoader.loadClass(NoiseSeeded.class, map.get("distribution"));
return new TreeLayer(density, range, items, noise.apply(2403L));
}
return new TreeLayer(density, range, items, new WhiteNoiseSampler(2403));
}
}