From e1cb46c8fdf5d5a055246c31a3c24a5cb347611e Mon Sep 17 00:00:00 2001 From: dfsek Date: Sun, 20 Dec 2020 02:21:19 -0700 Subject: [PATCH] basic structure implementation --- .../terra/api/structures/parser/Parser.java | 5 +-- .../parser/lang/ConstantExpression.java | 1 + .../lang/statements/EqualsStatement.java | 2 + .../script/builders/BlockFunctionBuilder.java | 26 +++++++++++ .../script/builders/SpawnCheckBuilder.java | 26 +++++++++++ .../script/functions/BlockFunction.java | 35 +++++++++++++++ .../script/functions/CheckFunction.java | 43 +++++++++++++++++++ .../terra/api/structures/world/AirCheck.java | 25 +++++++++++ .../terra/api/structures/world/LandCheck.java | 22 ++++++++++ .../api/structures/world/OceanCheck.java | 25 +++++++++++ .../api/structures/world/SpawnCheck.java | 17 ++++++++ .../src/test/java/structure/ParserTest.java | 2 +- .../test/java/structure/TokenizerTest.java | 2 +- common/src/test/resources/test.tesf | 8 ---- .../structure/load/LoadRawCommand.java | 21 +++++++++ 15 files changed, 246 insertions(+), 14 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/BlockFunctionBuilder.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/SpawnCheckBuilder.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/functions/CheckFunction.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/world/AirCheck.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/world/LandCheck.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/world/OceanCheck.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/world/SpawnCheck.java delete mode 100644 common/src/test/resources/test.tesf diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java index a971995c6..9df204285 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java @@ -63,7 +63,6 @@ public class Parser { private Keyword parseKeyword(List tokens, List functionAndArguments) throws ParseException { Token identifier = functionAndArguments.remove(0); - System.out.println("Parsing keyword at " + identifier.getStart()); checkType(identifier, Token.Type.IDENTIFIER); if(!keywords.contains(identifier.getContent())) throw new ParseException("No such keyword " + identifier.getContent() + ": " + identifier.getStart()); @@ -93,7 +92,7 @@ public class Parser { private Expression parseExpression(List tokens) throws ParseException { if(tokens.get(0).isConstant()) { - return new ConstantExpression(tokens.remove(0)); + return new ConstantExpression(tokens.remove(0).getContent()); } else return parseFunction(tokens, false); } @@ -103,7 +102,6 @@ public class Parser { while(tokens.size() > 0) { Token token = tokens.remove(0); - System.out.println(token); if(token.getType().equals(Token.Type.BLOCK_END)) break; functionArgs.add(token); if(token.getType().equals(Token.Type.STATEMENT_END)) { @@ -119,7 +117,6 @@ public class Parser { private Function parseFunction(List functionAndArguments, boolean fullStatement) throws ParseException { Token identifier = functionAndArguments.remove(0); - System.out.println("Parsing function at " + identifier.getStart()); checkType(identifier, Token.Type.IDENTIFIER); // First token must be identifier if(!functions.containsKey(identifier.getContent())) diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/ConstantExpression.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/ConstantExpression.java index bf82fe7af..fdd9a0f2a 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/ConstantExpression.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/ConstantExpression.java @@ -15,6 +15,7 @@ public class ConstantExpression implements Expression { return constant; } + @Override public Object apply(Location location, Chunk chunk) { return constant; diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/statements/EqualsStatement.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/statements/EqualsStatement.java index b55178685..a329a360f 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/statements/EqualsStatement.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/statements/EqualsStatement.java @@ -16,6 +16,8 @@ public class EqualsStatement implements Statement { @Override public Boolean apply(Location location) { + System.out.println(left.apply(location)); + System.out.println(right.apply(location)); return left.apply(location).equals(right.apply(location)); } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/BlockFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/BlockFunctionBuilder.java new file mode 100644 index 000000000..156453db7 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/BlockFunctionBuilder.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.api.structures.script.builders; + +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.structures.parser.FunctionBuilder; +import com.dfsek.terra.api.structures.parser.exceptions.ParseException; +import com.dfsek.terra.api.structures.script.functions.BlockFunction; + +import java.util.List; + +public class BlockFunctionBuilder implements FunctionBuilder { + private final TerraPlugin main; + + public BlockFunctionBuilder(TerraPlugin main) { + this.main = main; + } + + @Override + public BlockFunction build(List argumentList) throws ParseException { + return new BlockFunction(Integer.parseInt(argumentList.get(0)), Integer.parseInt(argumentList.get(1)), Integer.parseInt(argumentList.get(2)), main.getWorldHandle().createBlockData(argumentList.get(3))); + } + + @Override + public int getArguments() { + return 4; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/SpawnCheckBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/SpawnCheckBuilder.java new file mode 100644 index 000000000..a8010b304 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/SpawnCheckBuilder.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.api.structures.script.builders; + +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.structures.parser.FunctionBuilder; +import com.dfsek.terra.api.structures.parser.exceptions.ParseException; +import com.dfsek.terra.api.structures.script.functions.CheckFunction; + +import java.util.List; + +public class SpawnCheckBuilder implements FunctionBuilder { + private final TerraPlugin main; + + public SpawnCheckBuilder(TerraPlugin main) { + this.main = main; + } + + @Override + public CheckFunction build(List argumentList) throws ParseException { + return new CheckFunction(main, Integer.parseInt(argumentList.get(0)), Integer.parseInt(argumentList.get(1)), Integer.parseInt(argumentList.get(2))); + } + + @Override + public int getArguments() { + return 3; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java new file mode 100644 index 000000000..08c0411b2 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java @@ -0,0 +1,35 @@ +package com.dfsek.terra.api.structures.script.functions; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.world.Chunk; +import com.dfsek.terra.api.structures.parser.lang.Function; + +public class BlockFunction implements Function { + private final BlockData data; + private final int x, y, z; + + public BlockFunction(int x, int y, int z, BlockData data) { + this.data = data; + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public String name() { + return "block"; + } + + @Override + public Void apply(Location location) { + location.clone().add(x, y, z).getBlock().setBlockData(data, false); + return null; + } + + @Override + public Void apply(Location location, Chunk chunk) { + //TODO: do + return null; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/CheckFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/CheckFunction.java new file mode 100644 index 000000000..c6e92f269 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/CheckFunction.java @@ -0,0 +1,43 @@ +package com.dfsek.terra.api.structures.script.functions; + +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.lang.Function; +import com.dfsek.terra.api.structures.world.LandCheck; +import com.dfsek.terra.api.structures.world.OceanCheck; + +public class CheckFunction implements Function { + private final TerraPlugin main; + private final int x, y, z; + + public CheckFunction(TerraPlugin main, int x, int y, int z) { + this.main = main; + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public String name() { + return "check"; + } + + @Override + public String apply(Location location) { + if(new LandCheck(location.getWorld(), main).check(location.getBlockX() + x, location.getBlockY() + y, location.getBlockZ() + z)) + return "LAND"; + if(new OceanCheck(location.getWorld(), main).check(location.getBlockX() + x, location.getBlockY() + y, location.getBlockZ() + z)) + return "OCEAN"; + return "AIR"; + } + + @Override + public String apply(Location location, Chunk chunk) { + if(new LandCheck(location.getWorld(), main).check(location.getBlockX() + x, location.getBlockY() + y, location.getBlockZ() + z)) + return "LAND"; + if(new OceanCheck(location.getWorld(), main).check(location.getBlockX() + x, location.getBlockY() + y, location.getBlockZ() + z)) + return "OCEAN"; + return "AIR"; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/world/AirCheck.java b/common/src/main/java/com/dfsek/terra/api/structures/world/AirCheck.java new file mode 100644 index 000000000..9e7ff9f04 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/world/AirCheck.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.api.structures.world; + +import com.dfsek.terra.TerraWorld; +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.world.generation.GenerationPhase; +import com.dfsek.terra.biome.UserDefinedBiome; +import com.dfsek.terra.config.templates.BiomeTemplate; +import com.dfsek.terra.generation.config.WorldGenerator; + +public class AirCheck extends SpawnCheck { + public AirCheck(World world, TerraPlugin main) { + super(world, main); + } + + @Override + public boolean check(int x, int y, int z) { + TerraWorld tw = main.getWorld(world); + UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE); + BiomeTemplate c = b.getConfig(); + if(y <= c.getSeaLevel()) return false; + double elevation = ((WorldGenerator) b.getGenerator()).getElevation(x, z); + return b.getGenerator().getNoise(world, x, y, z) + elevation <= 0; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/world/LandCheck.java b/common/src/main/java/com/dfsek/terra/api/structures/world/LandCheck.java new file mode 100644 index 000000000..964dcd416 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/world/LandCheck.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.api.structures.world; + +import com.dfsek.terra.TerraWorld; +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.world.generation.GenerationPhase; +import com.dfsek.terra.biome.UserDefinedBiome; +import com.dfsek.terra.generation.config.WorldGenerator; + +public class LandCheck extends SpawnCheck { + public LandCheck(World world, TerraPlugin main) { + super(world, main); + } + + @Override + public boolean check(int x, int y, int z) { + TerraWorld tw = main.getWorld(world); + UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE); + double elevation = ((WorldGenerator) b.getGenerator()).getElevation(x, z); + return b.getGenerator().getNoise(world, x, y, z) + elevation > 0; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/world/OceanCheck.java b/common/src/main/java/com/dfsek/terra/api/structures/world/OceanCheck.java new file mode 100644 index 000000000..ef70cd0e2 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/world/OceanCheck.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.api.structures.world; + +import com.dfsek.terra.TerraWorld; +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.world.World; +import com.dfsek.terra.api.world.generation.GenerationPhase; +import com.dfsek.terra.biome.UserDefinedBiome; +import com.dfsek.terra.config.templates.BiomeTemplate; +import com.dfsek.terra.generation.config.WorldGenerator; + +public class OceanCheck extends SpawnCheck { + public OceanCheck(World world, TerraPlugin main) { + super(world, main); + } + + @Override + public boolean check(int x, int y, int z) { + TerraWorld tw = main.getWorld(world); + UserDefinedBiome b = (UserDefinedBiome) tw.getGrid().getBiome(x, z, GenerationPhase.POPULATE); + BiomeTemplate c = b.getConfig(); + if(y > c.getSeaLevel()) return false; + double elevation = ((WorldGenerator) b.getGenerator()).getElevation(x, z); + return b.getGenerator().getNoise(world, x, y, z) + elevation <= 0; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/world/SpawnCheck.java b/common/src/main/java/com/dfsek/terra/api/structures/world/SpawnCheck.java new file mode 100644 index 000000000..25bf32683 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/world/SpawnCheck.java @@ -0,0 +1,17 @@ +package com.dfsek.terra.api.structures.world; + +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.world.World; + +public abstract class SpawnCheck { + protected final World world; + protected final TerraPlugin main; + + protected SpawnCheck(World world, TerraPlugin main) { + this.world = world; + this.main = main; + } + + public abstract boolean check(int x, int y, int z); + +} diff --git a/common/src/test/java/structure/ParserTest.java b/common/src/test/java/structure/ParserTest.java index 29659085f..504b3de16 100644 --- a/common/src/test/java/structure/ParserTest.java +++ b/common/src/test/java/structure/ParserTest.java @@ -16,7 +16,7 @@ import java.util.List; public class ParserTest { @Test public void parse() throws IOException, ParseException { - Parser parser = new Parser(IOUtils.toString(getClass().getResourceAsStream("/test.tesf"))); + Parser parser = new Parser(IOUtils.toString(getClass().getResourceAsStream("/target/server/plugins/Terra/test.tesf"))); parser.addFunction("test", new FunctionBuilder() { @Override diff --git a/common/src/test/java/structure/TokenizerTest.java b/common/src/test/java/structure/TokenizerTest.java index 73e0fd6e2..fe7a01ae4 100644 --- a/common/src/test/java/structure/TokenizerTest.java +++ b/common/src/test/java/structure/TokenizerTest.java @@ -11,7 +11,7 @@ import java.io.IOException; public class TokenizerTest { @Test public void tokens() throws IOException, TokenizerException { - Tokenizer tokenizer = new Tokenizer(IOUtils.toString(getClass().getResourceAsStream("/test.tesf"))); + Tokenizer tokenizer = new Tokenizer(IOUtils.toString(getClass().getResourceAsStream("/target/server/plugins/Terra/test.tesf"))); // Actual run long l = System.nanoTime(); diff --git a/common/src/test/resources/test.tesf b/common/src/test/resources/test.tesf deleted file mode 100644 index 8fe2f603a..000000000 --- a/common/src/test/resources/test.tesf +++ /dev/null @@ -1,8 +0,0 @@ -test("hello", 1); -test("ghgj{}()\"\\hgjhgj", 3.4); - -if(test("hello", 1) == "a string literal") { - test("hello", 1); -} - -test("ghgj{}()\"\\hgjhgj", 3.4); \ No newline at end of file diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/structure/load/LoadRawCommand.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/structure/load/LoadRawCommand.java index 69b955da0..eda9606fb 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/structure/load/LoadRawCommand.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/command/command/structure/load/LoadRawCommand.java @@ -1,12 +1,23 @@ package com.dfsek.terra.bukkit.command.command.structure.load; +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.SpawnCheckBuilder; +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.stream.Collectors; @@ -26,6 +37,16 @@ public class LoadRawCommand extends LoadCommand implements DebugCommand { @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())); + parser.addFunction("check", new SpawnCheckBuilder(getMain())); + Block main = parser.parse(); + main.apply(new Location(new BukkitWorld(sender.getWorld()), sender.getLocation().getX(), sender.getLocation().getY(), sender.getLocation().getZ())); + + } catch(IOException | ParseException e) { + e.printStackTrace(); + } /* try { WorldHandle handle = ((TerraBukkitPlugin) getMain()).getWorldHandle();