mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
Load structure scripts into registry
This commit is contained in:
@@ -50,6 +50,7 @@ import java.util.Map;
|
||||
public class Parser {
|
||||
private final String data;
|
||||
private final Map<String, FunctionBuilder<? extends Function<?>>> functions = new HashMap<>();
|
||||
private String id;
|
||||
|
||||
public Parser(String data) {
|
||||
this.data = data;
|
||||
@@ -60,6 +61,10 @@ public class Parser {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse input
|
||||
*
|
||||
@@ -75,6 +80,14 @@ public class Parser {
|
||||
} catch(TokenizerException e) {
|
||||
throw new ParseException("Failed to tokenize input", e);
|
||||
}
|
||||
|
||||
// Parse ID
|
||||
ParserUtil.checkType(tokens.remove(0), Token.Type.ID); // First token must be ID
|
||||
Token idToken = tokens.get(0);
|
||||
ParserUtil.checkType(tokens.remove(0), Token.Type.STRING); // Second token must be string literal containing ID
|
||||
ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END);
|
||||
this.id = idToken.getContent();
|
||||
|
||||
// Check for dangling brackets
|
||||
int blockLevel = 0;
|
||||
for(Token t : tokens) {
|
||||
|
||||
@@ -1,4 +1,50 @@
|
||||
package com.dfsek.terra.api.structures.script;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.Chunk;
|
||||
import com.dfsek.terra.api.structures.parser.Parser;
|
||||
import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Block;
|
||||
import com.dfsek.terra.api.structures.script.builders.BlockFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.CheckFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class StructureScript {
|
||||
private final Block block;
|
||||
private final String id;
|
||||
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main) {
|
||||
Parser parser;
|
||||
try {
|
||||
parser = new Parser(IOUtils.toString(inputStream));
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
parser.addFunction("block", new BlockFunctionBuilder(main))
|
||||
.addFunction("check", new CheckFunctionBuilder(main));
|
||||
|
||||
try {
|
||||
block = parser.parse();
|
||||
} catch(ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.id = parser.getID();
|
||||
}
|
||||
|
||||
public void execute(Location location, Rotation rotation) {
|
||||
block.apply(location, rotation);
|
||||
}
|
||||
|
||||
public void execute(Location location, Chunk chunk, Rotation rotation) {
|
||||
block.apply(location, chunk, rotation);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +206,10 @@ public class Token {
|
||||
/**
|
||||
* Break statement
|
||||
*/
|
||||
BREAK
|
||||
BREAK,
|
||||
/**
|
||||
* ID declaration
|
||||
*/
|
||||
ID
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,9 @@ public class Tokenizer {
|
||||
if(tokenString.equals("break"))
|
||||
return new Token(tokenString, Token.Type.BREAK, new Position(reader.getLine(), reader.getIndex()));
|
||||
|
||||
if(tokenString.equals("id"))
|
||||
return new Token(tokenString, Token.Type.ID, new Position(reader.getLine(), reader.getIndex()));
|
||||
|
||||
return new Token(tokenString, Token.Type.IDENTIFIER, new Position(reader.getLine(), reader.getIndex()));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.dfsek.tectonic.loading.TypeRegistry;
|
||||
import com.dfsek.terra.api.LoaderRegistrar;
|
||||
import com.dfsek.terra.api.loot.LootTable;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
@@ -44,6 +45,7 @@ import com.dfsek.terra.registry.CarverRegistry;
|
||||
import com.dfsek.terra.registry.FloraRegistry;
|
||||
import com.dfsek.terra.registry.OreRegistry;
|
||||
import com.dfsek.terra.registry.PaletteRegistry;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import com.dfsek.terra.registry.StructureRegistry;
|
||||
import com.dfsek.terra.registry.TerraRegistry;
|
||||
import com.dfsek.terra.registry.TreeRegistry;
|
||||
@@ -78,6 +80,7 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
private final FloraRegistry floraRegistry;
|
||||
private final OreRegistry oreRegistry = new OreRegistry();
|
||||
private final TreeRegistry treeRegistry;
|
||||
private final ScriptRegistry scriptRegistry = new ScriptRegistry();
|
||||
|
||||
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
|
||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||
@@ -141,13 +144,19 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
abstractConfigLoader
|
||||
.registerLoader(LootTable.class, new LootTableLoader(loader, main)); // These loaders need access to the Loader instance to get files.
|
||||
loader
|
||||
.open("palettes").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new), main)).close()
|
||||
.open("palettes").thenNames(names -> names.forEach(System.out::println)).close()
|
||||
.open("ores").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new), main)).close()
|
||||
.open("flora").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new), main)).close()
|
||||
.open("carving").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new), main)).close()
|
||||
.open("biomes").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this, main)), main)).close()
|
||||
.open("grids").then(streams -> buildAll(new BiomeGridFactory(), biomeGridRegistry, abstractConfigLoader.load(streams, BiomeGridTemplate::new), main)).close();
|
||||
.open("palettes", ".yml").then(streams -> buildAll(new PaletteFactory(), paletteRegistry, abstractConfigLoader.load(streams, PaletteTemplate::new), main)).close()
|
||||
.open("ores", ".yml").then(streams -> buildAll(new OreFactory(), oreRegistry, abstractConfigLoader.load(streams, OreTemplate::new), main)).close()
|
||||
.open("flora", ".yml").then(streams -> buildAll(new FloraFactory(), floraRegistry, abstractConfigLoader.load(streams, FloraTemplate::new), main)).close()
|
||||
.open("carving", ".yml").then(streams -> buildAll(new CarverFactory(this), carverRegistry, abstractConfigLoader.load(streams, CarverTemplate::new), main)).close()
|
||||
.open("biomes", ".yml").then(streams -> buildAll(new BiomeFactory(this), biomeRegistry, abstractConfigLoader.load(streams, () -> new BiomeTemplate(this, main)), main)).close()
|
||||
.open("grids", ".yml").then(streams -> buildAll(new BiomeGridFactory(), biomeGridRegistry, abstractConfigLoader.load(streams, BiomeGridTemplate::new), main)).close();
|
||||
|
||||
|
||||
loader.open("structures/data", ".tesf").then(streams -> streams.forEach(stream -> {
|
||||
StructureScript structureScript = new StructureScript(stream, main);
|
||||
scriptRegistry.add(structureScript.getId(), structureScript);
|
||||
})).close();
|
||||
|
||||
for(UserDefinedBiome b : biomeRegistry.entries()) {
|
||||
try {
|
||||
Objects.requireNonNull(b.getErode()); // Throws NPE if it cannot load erosion biomes.
|
||||
@@ -231,6 +240,10 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
.registerLoader(Tree.class, treeRegistry);
|
||||
}
|
||||
|
||||
public ScriptRegistry getScriptRegistry() {
|
||||
return scriptRegistry;
|
||||
}
|
||||
|
||||
public BiomeRegistry getBiomeRegistry() {
|
||||
return biomeRegistry;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ public class FolderLoader extends Loader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(String directory) {
|
||||
protected void load(String directory, String extension) {
|
||||
File newPath = new File(path.toFile(), directory);
|
||||
newPath.mkdirs();
|
||||
try(Stream<Path> paths = Files.walk(newPath.toPath())) {
|
||||
paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(".yml")).forEach(file -> {
|
||||
paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(extension)).forEach(file -> {
|
||||
try {
|
||||
streams.put(newPath.toURI().relativize(file.toUri()).getPath(), new FileInputStream(file.toFile()));
|
||||
} catch(FileNotFoundException e) {
|
||||
|
||||
@@ -45,14 +45,15 @@ public abstract class Loader {
|
||||
* Open a subdirectory.
|
||||
*
|
||||
* @param directory Directory to open
|
||||
* @param extension
|
||||
*/
|
||||
public Loader open(String directory) {
|
||||
public Loader open(String directory, String extension) {
|
||||
if(streams.size() != 0) throw new IllegalStateException("Attempted to load new directory before closing existing InputStreams");
|
||||
load(directory);
|
||||
load(directory, extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void load(String directory);
|
||||
protected abstract void load(String directory, String extension);
|
||||
|
||||
/**
|
||||
* Close all InputStreams opened.
|
||||
|
||||
@@ -24,11 +24,11 @@ public class ZIPLoader extends Loader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(String directory) {
|
||||
protected void load(String directory, String extension) {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(".yml")) {
|
||||
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) {
|
||||
try {
|
||||
streams.put(entry.getName(), file.getInputStream(entry));
|
||||
} catch(IOException e) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.dfsek.terra.registry;
|
||||
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
|
||||
public class ScriptRegistry extends TerraRegistry<StructureScript> {
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
id "testScript";
|
||||
|
||||
test("minecraft:green_w" + "ool", (2 * (3+1) * (2 * (1+1))));
|
||||
//
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.bukkit.command.command.structure.load;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.bukkit.command.DebugCommand;
|
||||
import com.dfsek.terra.bukkit.command.PlayerCommand;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -7,9 +9,6 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -20,17 +19,14 @@ public class LoadCommand extends PlayerCommand implements DebugCommand {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public List<String> getStructureNames() {
|
||||
public List<String> getStructureNames(World world) {
|
||||
List<String> names = new ArrayList<>();
|
||||
File structureDir = new File(getMain().getDataFolder() + File.separator + "export" + File.separator + "structures");
|
||||
if(!structureDir.exists()) return Collections.emptyList();
|
||||
Path structurePath = structureDir.toPath();
|
||||
TerraWorld terraWorld = getMain().getWorld(world);
|
||||
|
||||
terraWorld.getConfig().getScriptRegistry().forEach(script -> {
|
||||
names.add(script.getId());
|
||||
});
|
||||
|
||||
FilenameFilter filter = (dir, name) -> name.endsWith(".tstructure");
|
||||
for(File f : structureDir.listFiles(filter)) {
|
||||
String path = structurePath.relativize(f.toPath()).toString();
|
||||
names.add(path.substring(0, path.length() - 11));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public class LoadFullCommand extends LoadCommand implements DebugCommand {
|
||||
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] args) {
|
||||
switch(args.length) {
|
||||
case 1:
|
||||
return getStructureNames().stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
|
||||
return Collections.emptyList(); //getStructureNames().stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
|
||||
case 2:
|
||||
return Stream.of("0", "90", "180", "270").filter(string -> string.toUpperCase().startsWith(args[1].toUpperCase())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
package com.dfsek.terra.bukkit.command.command.structure.load;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.structures.parser.Parser;
|
||||
import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Block;
|
||||
import com.dfsek.terra.api.structures.script.builders.BlockFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.CheckFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.bukkit.BukkitWorld;
|
||||
import com.dfsek.terra.bukkit.command.DebugCommand;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@@ -37,24 +29,13 @@ public class LoadRawCommand extends LoadCommand implements DebugCommand {
|
||||
} else sign.setLine(2, data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) {
|
||||
try {
|
||||
Parser parser = new Parser(IOUtils.toString(new FileInputStream(new File(getMain().getDataFolder(), "test.tesf"))));
|
||||
parser.addFunction("block", new BlockFunctionBuilder(getMain()))
|
||||
.addFunction("check", new CheckFunctionBuilder(getMain()));
|
||||
TerraWorld terraWorld = getMain().getWorld(new BukkitWorld(sender.getWorld()));
|
||||
|
||||
System.out.println("Parsing...");
|
||||
terraWorld.getConfig().getScriptRegistry().get(args[0]).execute(new Location(new BukkitWorld(sender.getWorld()), sender.getLocation().getX(), sender.getLocation().getY(), sender.getLocation().getZ()), Rotation.fromDegrees(90 * ThreadLocalRandom.current().nextInt(4)));
|
||||
|
||||
Block main = parser.parse();
|
||||
|
||||
System.out.println("Done parsing");
|
||||
|
||||
main.apply(new Location(new BukkitWorld(sender.getWorld()), sender.getLocation().getX(), sender.getLocation().getY(), sender.getLocation().getZ()), Rotation.fromDegrees(90 * ThreadLocalRandom.current().nextInt(4)));
|
||||
|
||||
} catch(IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/*
|
||||
try {
|
||||
WorldHandle handle = ((TerraBukkitPlugin) getMain()).getWorldHandle();
|
||||
@@ -130,7 +111,7 @@ public class LoadRawCommand extends LoadCommand implements DebugCommand {
|
||||
@Override
|
||||
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] args) {
|
||||
if(args.length == 1) {
|
||||
return getStructureNames().stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
|
||||
return getStructureNames(new BukkitWorld(((Player) commandSender).getWorld())).stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user