From 63e59692e2cc7c40f2b13c992f5bcabad85d97c2 Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 23 Dec 2020 03:08:31 -0700 Subject: [PATCH] Implement StructureFunction and temp RandomFunction --- .../structures/script/StructureScript.java | 9 ++- .../builders/RandomFunctionBuilder.java | 28 +++++++ .../builders/StructureFunctionBuilder.java | 46 ++++++++++++ .../script/functions/RandomFunction.java | 46 ++++++++++++ .../script/functions/StructureFunction.java | 73 +++++++++++++++++++ .../dfsek/terra/config/base/ConfigPack.java | 2 +- 6 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/RandomFunctionBuilder.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/StructureFunctionBuilder.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/functions/RandomFunction.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/functions/StructureFunction.java diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java b/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java index df52c06e6..32805bfa0 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/StructureScript.java @@ -8,7 +8,10 @@ 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.script.builders.RandomFunctionBuilder; +import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder; import com.dfsek.terra.api.structures.structure.Rotation; +import com.dfsek.terra.registry.ScriptRegistry; import org.apache.commons.io.IOUtils; import java.io.IOException; @@ -18,7 +21,7 @@ public class StructureScript { private final Block block; private final String id; - public StructureScript(InputStream inputStream, TerraPlugin main) { + public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry) { Parser parser; try { parser = new Parser(IOUtils.toString(inputStream)); @@ -26,7 +29,9 @@ public class StructureScript { throw new RuntimeException(e); } parser.addFunction("block", new BlockFunctionBuilder(main)) - .addFunction("check", new CheckFunctionBuilder(main)); + .addFunction("check", new CheckFunctionBuilder(main)) + .addFunction("structure", new StructureFunctionBuilder(registry, main)) + .addFunction("randomInt", new RandomFunctionBuilder()); try { block = parser.parse(); diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RandomFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RandomFunctionBuilder.java new file mode 100644 index 000000000..ec84d5c36 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RandomFunctionBuilder.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.api.structures.script.builders; + +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.functions.FunctionBuilder; +import com.dfsek.terra.api.structures.script.functions.RandomFunction; +import com.dfsek.terra.api.structures.tokenizer.Position; + +import java.util.List; + +public class RandomFunctionBuilder implements FunctionBuilder { + @SuppressWarnings("unchecked") + @Override + public RandomFunction build(List> argumentList, Position position) throws ParseException { + return new RandomFunction((Returnable) argumentList.get(0), position); + } + + @Override + public int argNumber() { + return 1; + } + + @Override + public Returnable.ReturnType getArgument(int position) { + if(position == 0) return Returnable.ReturnType.NUMBER; + return null; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/StructureFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/StructureFunctionBuilder.java new file mode 100644 index 000000000..33da88114 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/StructureFunctionBuilder.java @@ -0,0 +1,46 @@ +package com.dfsek.terra.api.structures.script.builders; + +import com.dfsek.terra.api.platform.TerraPlugin; +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.functions.FunctionBuilder; +import com.dfsek.terra.api.structures.script.functions.StructureFunction; +import com.dfsek.terra.api.structures.tokenizer.Position; +import com.dfsek.terra.registry.ScriptRegistry; + +import java.util.List; + +public class StructureFunctionBuilder implements FunctionBuilder { + private final ScriptRegistry registry; + private final TerraPlugin main; + + public StructureFunctionBuilder(ScriptRegistry registry, TerraPlugin main) { + this.registry = registry; + this.main = main; + } + + @SuppressWarnings("unchecked") + @Override + public StructureFunction build(List> argumentList, Position position) throws ParseException { + return new StructureFunction((Returnable) argumentList.get(0), (Returnable) argumentList.get(1), (Returnable) argumentList.get(2), (Returnable) argumentList.get(3), registry, position, main); + } + + @Override + public int argNumber() { + return 4; + } + + @Override + public Returnable.ReturnType getArgument(int position) { + switch(position) { + case 0: + case 1: + case 2: + return Returnable.ReturnType.NUMBER; + case 3: + return Returnable.ReturnType.STRING; + default: + return null; + } + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RandomFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RandomFunction.java new file mode 100644 index 000000000..d7b478ff1 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RandomFunction.java @@ -0,0 +1,46 @@ +package com.dfsek.terra.api.structures.script.functions; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.world.Chunk; +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.structure.Rotation; +import com.dfsek.terra.api.structures.tokenizer.Position; + +import java.util.concurrent.ThreadLocalRandom; + +public class RandomFunction implements Function { + private final Returnable numberReturnable; + private final Position position; + + public RandomFunction(Returnable numberReturnable, Position position) { + this.numberReturnable = numberReturnable; + this.position = position; + } + + + @Override + public String name() { + return "randomInt"; + } + + @Override + public ReturnType returnType() { + return ReturnType.NUMBER; + } + + @Override + public Integer apply(Location location, Rotation rotation) { + return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, rotation).intValue()); // TODO: deterministic random + } + + @Override + public Integer apply(Location location, Chunk chunk, Rotation rotation) { + return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, chunk, rotation).intValue()); + } + + @Override + public Position getPosition() { + return position; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/StructureFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/StructureFunction.java new file mode 100644 index 000000000..006901c07 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/StructureFunction.java @@ -0,0 +1,73 @@ +package com.dfsek.terra.api.structures.script.functions; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.math.vector.Vector2; +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.world.Chunk; +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.script.StructureScript; +import com.dfsek.terra.api.structures.structure.Rotation; +import com.dfsek.terra.api.structures.structure.RotationUtil; +import com.dfsek.terra.api.structures.tokenizer.Position; +import com.dfsek.terra.registry.ScriptRegistry; +import net.jafama.FastMath; + +public class StructureFunction implements Function { + private final ScriptRegistry registry; + private final Returnable id; + private final Returnable x, y, z; + private final Position position; + private final TerraPlugin main; + + public StructureFunction(Returnable x, Returnable y, Returnable z, Returnable id, ScriptRegistry registry, Position position, TerraPlugin main) { + this.registry = registry; + this.id = id; + this.position = position; + this.x = x; + this.y = y; + this.z = z; + this.main = main; + } + + @Override + public String name() { + return "structure"; + } + + @Override + public ReturnType returnType() { + return ReturnType.VOID; + } + + @Override + public Void apply(Location location, Rotation rotation) { + System.out.println("executing structure function"); + + Vector2 xz = new Vector2(x.apply(location, rotation).doubleValue(), z.apply(location, rotation).doubleValue()); + + RotationUtil.rotateVector(xz, rotation); + + StructureScript script = registry.get(id.apply(location, rotation)); + if(script == null) { + main.getLogger().severe("No such structure " + id.apply(location, rotation)); + return null; + } + + Location location1 = location.clone().add(FastMath.roundToInt(xz.getX()), y.apply(location, rotation).intValue(), FastMath.roundToInt(xz.getZ())); + + script.execute(location1, rotation); + + return null; + } + + @Override + public Void apply(Location location, Chunk chunk, Rotation rotation) { + return null; + } + + @Override + public Position getPosition() { + return position; + } +} diff --git a/common/src/main/java/com/dfsek/terra/config/base/ConfigPack.java b/common/src/main/java/com/dfsek/terra/config/base/ConfigPack.java index f7d61c590..8fdda699f 100644 --- a/common/src/main/java/com/dfsek/terra/config/base/ConfigPack.java +++ b/common/src/main/java/com/dfsek/terra/config/base/ConfigPack.java @@ -153,7 +153,7 @@ public class ConfigPack implements LoaderRegistrar { loader.open("structures/data", ".tesf").then(streams -> streams.forEach(stream -> { - StructureScript structureScript = new StructureScript(stream, main); + StructureScript structureScript = new StructureScript(stream, main, scriptRegistry); scriptRegistry.add(structureScript.getId(), structureScript); })).close();