From 7fe7dac57a88b79c33ca7aecdb9ffe108daf461c Mon Sep 17 00:00:00 2001 From: dfsek Date: Wed, 23 Dec 2020 15:09:42 -0700 Subject: [PATCH] implement RecursionsFunction --- .../api/structures/parser/lang/Block.java | 8 ++-- .../api/structures/parser/lang/Item.java | 4 +- .../lang/constants/ConstantExpression.java | 4 +- .../parser/lang/keywords/BreakKeyword.java | 4 +- .../parser/lang/keywords/ContinueKeyword.java | 4 +- .../parser/lang/keywords/IfKeyword.java | 8 ++-- .../parser/lang/keywords/ReturnKeyword.java | 4 +- .../parser/lang/keywords/WhileKeyword.java | 12 +++--- .../lang/operations/BinaryOperation.java | 8 ++-- .../lang/operations/UnaryOperation.java | 8 ++-- .../parser/lang/variables/Assignment.java | 8 ++-- .../parser/lang/variables/Getter.java | 4 +- .../structures/script/StructureScript.java | 12 +++--- .../builders/RecursionsFunctionBuilder.java | 26 ++++++++++++ .../builders/StructureFunctionBuilder.java | 12 +++--- .../script/functions/BlockFunction.java | 8 ++-- .../script/functions/CheckFunction.java | 18 ++++----- .../script/functions/RandomFunction.java | 8 ++-- .../script/functions/RecursionsFunction.java | 40 +++++++++++++++++++ .../script/functions/StructureFunction.java | 30 ++++++++++---- .../api/structures/structure/Rotation.java | 4 ++ .../src/test/java/structure/ParserTest.java | 10 ++--- .../structure/load/LoadRawCommand.java | 9 ++++- 23 files changed, 173 insertions(+), 80 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/RecursionsFunctionBuilder.java create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/functions/RecursionsFunction.java diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java index 1e60004f4..5a3f7a975 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Block.java @@ -21,9 +21,9 @@ public class Block implements Item { } @Override - public ReturnLevel apply(Location location, Rotation rotation) { + public ReturnLevel apply(Location location, Rotation rotation, int recursions) { for(Item item : items) { - Object result = item.apply(location, rotation); + Object result = item.apply(location, rotation, recursions); if(result instanceof ReturnLevel) { ReturnLevel level = (ReturnLevel) result; if(!level.equals(ReturnLevel.NONE)) return level; @@ -33,9 +33,9 @@ public class Block implements Item { } @Override - public ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { + public ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { for(Item item : items) { - Object result = item.apply(location, chunk, rotation); + Object result = item.apply(location, chunk, rotation, recursions); if(result instanceof ReturnLevel) { ReturnLevel level = (ReturnLevel) result; if(!level.equals(ReturnLevel.NONE)) return level; diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Item.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Item.java index 7cc895eaf..4ec95cbfd 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Item.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Item.java @@ -6,9 +6,9 @@ import com.dfsek.terra.api.structures.structure.Rotation; import com.dfsek.terra.api.structures.tokenizer.Position; public interface Item { - T apply(Location location, Rotation rotation); + T apply(Location location, Rotation rotation, int recursions); - T apply(Location location, Chunk chunk, Rotation rotation); + T apply(Location location, Chunk chunk, Rotation rotation, int recursions); Position getPosition(); } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/constants/ConstantExpression.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/constants/ConstantExpression.java index 05b276897..a4b54c470 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/constants/ConstantExpression.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/constants/ConstantExpression.java @@ -16,13 +16,13 @@ public abstract class ConstantExpression implements Returnable { } @Override - public T apply(Location location, Rotation rotation) { + public T apply(Location location, Rotation rotation, int recursions) { return constant; } @Override - public T apply(Location location, Chunk chunk, Rotation rotation) { + public T apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return constant; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/BreakKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/BreakKeyword.java index c08e918e4..ac03e792e 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/BreakKeyword.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/BreakKeyword.java @@ -15,12 +15,12 @@ public class BreakKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Rotation rotation, int recursions) { return Block.ReturnLevel.BREAK; } @Override - public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return Block.ReturnLevel.BREAK; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ContinueKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ContinueKeyword.java index 2ff17ad67..67ac5a0b2 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ContinueKeyword.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ContinueKeyword.java @@ -15,12 +15,12 @@ public class ContinueKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Rotation rotation, int recursions) { return Block.ReturnLevel.CONTINUE; } @Override - public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return Block.ReturnLevel.CONTINUE; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/IfKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/IfKeyword.java index c148465d8..8d51f7d10 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/IfKeyword.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/IfKeyword.java @@ -20,14 +20,14 @@ public class IfKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Rotation rotation) { - if(statement.apply(location, rotation)) return conditional.apply(location, rotation); + public Block.ReturnLevel apply(Location location, Rotation rotation, int recursions) { + if(statement.apply(location, rotation, recursions)) return conditional.apply(location, rotation, recursions); return Block.ReturnLevel.NONE; } @Override - public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { - if(statement.apply(location, chunk, rotation)) return conditional.apply(location, chunk, rotation); + public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + if(statement.apply(location, chunk, rotation, recursions)) return conditional.apply(location, chunk, rotation, recursions); return Block.ReturnLevel.NONE; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ReturnKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ReturnKeyword.java index d0aa6eafc..c4c46b151 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ReturnKeyword.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/ReturnKeyword.java @@ -15,12 +15,12 @@ public class ReturnKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Rotation rotation, int recursions) { return Block.ReturnLevel.RETURN; } @Override - public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { + public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return Block.ReturnLevel.RETURN; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/WhileKeyword.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/WhileKeyword.java index 6b8023281..889f279f9 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/WhileKeyword.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/keywords/WhileKeyword.java @@ -20,9 +20,9 @@ public class WhileKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Rotation rotation) { - while(statement.apply(location, rotation)) { - Block.ReturnLevel level = conditional.apply(location, rotation); + public Block.ReturnLevel apply(Location location, Rotation rotation, int recursions) { + while(statement.apply(location, rotation, recursions)) { + Block.ReturnLevel level = conditional.apply(location, rotation, recursions); if(level.equals(Block.ReturnLevel.BREAK)) break; if(level.equals(Block.ReturnLevel.RETURN)) return Block.ReturnLevel.RETURN; } @@ -30,9 +30,9 @@ public class WhileKeyword implements Keyword { } @Override - public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation) { - while(statement.apply(location, chunk, rotation)) { - Block.ReturnLevel level = conditional.apply(location, chunk, rotation); + public Block.ReturnLevel apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + while(statement.apply(location, chunk, rotation, recursions)) { + Block.ReturnLevel level = conditional.apply(location, chunk, rotation, recursions); if(level.equals(Block.ReturnLevel.BREAK)) break; if(level.equals(Block.ReturnLevel.RETURN)) return Block.ReturnLevel.RETURN; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java index ef5642cd5..a9c1e7f51 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/BinaryOperation.java @@ -25,12 +25,12 @@ public abstract class BinaryOperation implements Returnable { } @Override - public O apply(Location location, Rotation rotation) { - return apply(left.apply(location, rotation), right.apply(location, rotation)); + public O apply(Location location, Rotation rotation, int recursions) { + return apply(left.apply(location, rotation, recursions), right.apply(location, rotation, recursions)); } @Override - public O apply(Location location, Chunk chunk, Rotation rotation) { - return apply(left.apply(location, chunk, rotation), right.apply(location, chunk, rotation)); + public O apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + return apply(left.apply(location, chunk, rotation, recursions), right.apply(location, chunk, rotation, recursions)); } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java index 68e588cd0..689edd476 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/operations/UnaryOperation.java @@ -18,13 +18,13 @@ public abstract class UnaryOperation implements Returnable { public abstract T apply(T input); @Override - public T apply(Location location, Rotation rotation) { - return apply(input.apply(location, rotation)); + public T apply(Location location, Rotation rotation, int recursions) { + return apply(input.apply(location, rotation, recursions)); } @Override - public T apply(Location location, Chunk chunk, Rotation rotation) { - return apply(input.apply(location, chunk, rotation)); + public T apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + return apply(input.apply(location, chunk, rotation, recursions)); } @Override diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Assignment.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Assignment.java index c18988e5b..169e4b4d8 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Assignment.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Assignment.java @@ -19,15 +19,15 @@ public class Assignment implements Item { } @Override - public T apply(Location location, Rotation rotation) { - T val = value.apply(location, rotation); + public T apply(Location location, Rotation rotation, int recursions) { + T val = value.apply(location, rotation, recursions); delegate.setValue(val); return val; } @Override - public T apply(Location location, Chunk chunk, Rotation rotation) { - T val = value.apply(location, chunk, rotation); + public T apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + T val = value.apply(location, chunk, rotation, recursions); delegate.setValue(val); return val; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Getter.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Getter.java index f8922b840..2383e0a5a 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Getter.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/variables/Getter.java @@ -19,12 +19,12 @@ public class Getter implements Returnable { } @Override - public Object apply(Location location, Rotation rotation) { + public Object apply(Location location, Rotation rotation, int recursions) { return delegate.getValue(); } @Override - public Object apply(Location location, Chunk chunk, Rotation rotation) { + public Object apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return delegate.getValue(); } 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 32805bfa0..7c850ed9c 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 @@ -9,6 +9,7 @@ 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.RecursionsFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder; import com.dfsek.terra.api.structures.structure.Rotation; import com.dfsek.terra.registry.ScriptRegistry; @@ -31,7 +32,8 @@ public class StructureScript { parser.addFunction("block", new BlockFunctionBuilder(main)) .addFunction("check", new CheckFunctionBuilder(main)) .addFunction("structure", new StructureFunctionBuilder(registry, main)) - .addFunction("randomInt", new RandomFunctionBuilder()); + .addFunction("randomInt", new RandomFunctionBuilder()) + .addFunction("recursions", new RecursionsFunctionBuilder()); try { block = parser.parse(); @@ -41,12 +43,12 @@ public class StructureScript { this.id = parser.getID(); } - public void execute(Location location, Rotation rotation) { - block.apply(location, rotation); + public void execute(Location location, Rotation rotation, int recursions) { + block.apply(location, rotation, recursions); } - public void execute(Location location, Chunk chunk, Rotation rotation) { - block.apply(location, chunk, rotation); + public void execute(Location location, Chunk chunk, Rotation rotation, int recursions) { + block.apply(location, chunk, rotation, recursions); } public String getId() { diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RecursionsFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RecursionsFunctionBuilder.java new file mode 100644 index 000000000..5fc66977d --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/RecursionsFunctionBuilder.java @@ -0,0 +1,26 @@ +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.RecursionsFunction; +import com.dfsek.terra.api.structures.tokenizer.Position; + +import java.util.List; + +public class RecursionsFunctionBuilder implements FunctionBuilder { + @Override + public RecursionsFunction build(List> argumentList, Position position) throws ParseException { + return new RecursionsFunction(position); + } + + @Override + public int argNumber() { + return 0; + } + + @Override + public Returnable.ReturnType getArgument(int position) { + 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 index 33da88114..044bd97d6 100644 --- 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 @@ -9,6 +9,7 @@ import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.registry.ScriptRegistry; import java.util.List; +import java.util.stream.Collectors; public class StructureFunctionBuilder implements FunctionBuilder { private final ScriptRegistry registry; @@ -22,12 +23,15 @@ public class StructureFunctionBuilder implements FunctionBuilder> 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); + if(argumentList.size() < 5) throw new ParseException("Expected rotations: " + position); + + return new StructureFunction((Returnable) argumentList.remove(0), (Returnable) argumentList.remove(0), (Returnable) argumentList.remove(0), (Returnable) argumentList.remove(0), + argumentList.stream().map(item -> ((Returnable) item)).collect(Collectors.toList()), registry, position, main); } @Override public int argNumber() { - return 4; + return -1; } @Override @@ -37,10 +41,8 @@ public class StructureFunctionBuilder implements FunctionBuilder { } @Override - public Void apply(Location location, Rotation rotation) { - Vector2 xz = new Vector2(x.apply(location, rotation).doubleValue(), z.apply(location, rotation).doubleValue()); + public Void apply(Location location, Rotation rotation, int recursions) { + Vector2 xz = new Vector2(x.apply(location, rotation, recursions).doubleValue(), z.apply(location, rotation, recursions).doubleValue()); RotationUtil.rotateVector(xz, rotation); - location.clone().add(FastMath.roundToInt(xz.getX()), y.apply(location, rotation).intValue(), FastMath.roundToInt(xz.getZ())).getBlock().setBlockData(data, false); + location.clone().add(FastMath.roundToInt(xz.getX()), y.apply(location, rotation, recursions).intValue(), FastMath.roundToInt(xz.getZ())).getBlock().setBlockData(data, false); return null; } @Override - public Void apply(Location location, Chunk chunk, Rotation rotation) { + public Void apply(Location location, Chunk chunk, Rotation rotation, int recursions) { //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 index 9782892b1..c36188658 100644 --- 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 @@ -33,19 +33,19 @@ public class CheckFunction implements Function { return "check"; } - private Vector3 getVector(Location location, Chunk chunk, Rotation rotation) { - Vector2 xz = chunk == null ? new Vector2(x.apply(location, rotation).doubleValue(), z.apply(location, rotation).doubleValue()) - : new Vector2(x.apply(location, chunk, rotation).doubleValue(), z.apply(location, chunk, rotation).doubleValue()); + private Vector3 getVector(Location location, Chunk chunk, Rotation rotation, int recursions) { + Vector2 xz = chunk == null ? new Vector2(x.apply(location, rotation, recursions).doubleValue(), z.apply(location, rotation, recursions).doubleValue()) + : new Vector2(x.apply(location, chunk, rotation, recursions).doubleValue(), z.apply(location, chunk, rotation, recursions).doubleValue()); RotationUtil.rotateVector(xz, rotation); - return location.clone().add(chunk == null ? new Vector3(FastMath.roundToInt(xz.getX()), y.apply(location, rotation).intValue(), FastMath.roundToInt(xz.getZ())) - : new Vector3(FastMath.roundToInt(xz.getX()), y.apply(location, chunk, rotation).intValue(), FastMath.roundToInt(xz.getZ()))).toVector(); + return location.clone().add(chunk == null ? new Vector3(FastMath.roundToInt(xz.getX()), y.apply(location, rotation, recursions).intValue(), FastMath.roundToInt(xz.getZ())) + : new Vector3(FastMath.roundToInt(xz.getX()), y.apply(location, chunk, rotation, recursions).intValue(), FastMath.roundToInt(xz.getZ()))).toVector(); } @Override - public String apply(Location location, Rotation rotation) { - return apply(getVector(location, null, rotation), location.getWorld()); + public String apply(Location location, Rotation rotation, int recursions) { + return apply(getVector(location, null, rotation, recursions), location.getWorld()); } private String apply(Vector3 vector, World world) { @@ -57,8 +57,8 @@ public class CheckFunction implements Function { } @Override - public String apply(Location location, Chunk chunk, Rotation rotation) { - return apply(getVector(location, chunk, rotation), location.getWorld()); + public String apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + return apply(getVector(location, chunk, rotation, recursions), location.getWorld()); } @Override 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 index d7b478ff1..c65b5d598 100644 --- 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 @@ -30,13 +30,13 @@ public class RandomFunction implements Function { } @Override - public Integer apply(Location location, Rotation rotation) { - return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, rotation).intValue()); // TODO: deterministic random + public Integer apply(Location location, Rotation rotation, int recursions) { + return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, rotation, recursions).intValue()); // TODO: deterministic random } @Override - public Integer apply(Location location, Chunk chunk, Rotation rotation) { - return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, chunk, rotation).intValue()); + public Integer apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + return ThreadLocalRandom.current().nextInt(numberReturnable.apply(location, chunk, rotation, recursions).intValue()); } @Override diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RecursionsFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RecursionsFunction.java new file mode 100644 index 000000000..2089f6af9 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/RecursionsFunction.java @@ -0,0 +1,40 @@ +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.functions.Function; +import com.dfsek.terra.api.structures.structure.Rotation; +import com.dfsek.terra.api.structures.tokenizer.Position; + +public class RecursionsFunction implements Function { + private final Position position; + + public RecursionsFunction(Position position) { + this.position = position; + } + + @Override + public String name() { + return "recursions"; + } + + @Override + public ReturnType returnType() { + return ReturnType.NUMBER; + } + + @Override + public Number apply(Location location, Rotation rotation, int recursions) { + return recursions; + } + + @Override + public Number apply(Location location, Chunk chunk, Rotation rotation, int recursions) { + return recursions; + } + + @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 index 006901c07..a464e21fc 100644 --- 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 @@ -13,14 +13,18 @@ import com.dfsek.terra.api.structures.tokenizer.Position; import com.dfsek.terra.registry.ScriptRegistry; import net.jafama.FastMath; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + 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; + private final List> rotations; - public StructureFunction(Returnable x, Returnable y, Returnable z, Returnable id, ScriptRegistry registry, Position position, TerraPlugin main) { + public StructureFunction(Returnable x, Returnable y, Returnable z, Returnable id, List> rotations, ScriptRegistry registry, Position position, TerraPlugin main) { this.registry = registry; this.id = id; this.position = position; @@ -28,6 +32,7 @@ public class StructureFunction implements Function { this.y = y; this.z = z; this.main = main; + this.rotations = rotations; } @Override @@ -41,28 +46,37 @@ public class StructureFunction implements Function { } @Override - public Void apply(Location location, Rotation rotation) { + public Void apply(Location location, Rotation rotation, int recursions) { System.out.println("executing structure function"); - Vector2 xz = new Vector2(x.apply(location, rotation).doubleValue(), z.apply(location, rotation).doubleValue()); + Vector2 xz = new Vector2(x.apply(location, rotation, recursions).doubleValue(), z.apply(location, rotation, recursions).doubleValue()); RotationUtil.rotateVector(xz, rotation); - StructureScript script = registry.get(id.apply(location, rotation)); + StructureScript script = registry.get(id.apply(location, rotation, recursions)); if(script == null) { - main.getLogger().severe("No such structure " + id.apply(location, rotation)); + main.getLogger().severe("No such structure " + id.apply(location, rotation, recursions)); return null; } - Location location1 = location.clone().add(FastMath.roundToInt(xz.getX()), y.apply(location, rotation).intValue(), FastMath.roundToInt(xz.getZ())); + Rotation rotation1; + String rotString = rotations.get(ThreadLocalRandom.current().nextInt(rotations.size())).apply(location, rotation, recursions); + try { + rotation1 = Rotation.valueOf(rotString); + } catch(IllegalArgumentException e) { + main.getLogger().severe("Invalid rotation " + rotString); + return null; + } - script.execute(location1, rotation); + Location location1 = location.clone().add(FastMath.roundToInt(xz.getX()), y.apply(location, rotation, recursions).intValue(), FastMath.roundToInt(xz.getZ())); + + script.execute(location1, rotation.rotate(rotation1), recursions + 1); return null; } @Override - public Void apply(Location location, Chunk chunk, Rotation rotation) { + public Void apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return null; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/structure/Rotation.java b/common/src/main/java/com/dfsek/terra/api/structures/structure/Rotation.java index 8efbff230..f81c8f63e 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/structure/Rotation.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/structure/Rotation.java @@ -45,6 +45,10 @@ public enum Rotation { } } + public Rotation rotate(Rotation rotation) { + return fromDegrees(this.getDegrees() + rotation.getDegrees()); + } + public enum Axis { X, Y, Z } diff --git a/common/src/test/java/structure/ParserTest.java b/common/src/test/java/structure/ParserTest.java index 4361f3083..d59a7bd8e 100644 --- a/common/src/test/java/structure/ParserTest.java +++ b/common/src/test/java/structure/ParserTest.java @@ -51,9 +51,9 @@ public class ParserTest { long t = System.nanoTime() - l; System.out.println("Took " + (double) t / 1000000); - block.apply(null, Rotation.NONE); + block.apply(null, Rotation.NONE, recursions); - block.apply(null, Rotation.NONE); + block.apply(null, Rotation.NONE, recursions); } private static class Test1 implements Function { @@ -68,13 +68,13 @@ public class ParserTest { } @Override - public Void apply(Location location, Rotation rotation) { - System.out.println("string: " + a.apply(location, rotation) + ", double: " + b.apply(location, rotation)); + public Void apply(Location location, Rotation rotation, int recursions) { + System.out.println("string: " + a.apply(location, rotation, recursions) + ", double: " + b.apply(location, rotation, recursions)); return null; } @Override - public Void apply(Location location, Chunk chunk, Rotation rotation) { + public Void apply(Location location, Chunk chunk, Rotation rotation, int recursions) { return null; } 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 8a2fe133a..92b185ca8 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 @@ -32,9 +32,14 @@ public class LoadRawCommand extends LoadCommand implements DebugCommand { @Override public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) { - TerraWorld terraWorld = getMain().getWorld(new BukkitWorld(sender.getWorld())); - 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))); + + TerraWorld terraWorld = getMain().getWorld(new BukkitWorld(sender.getWorld())); + long t = System.nanoTime(); + 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)), 0); + long l = System.nanoTime() - t; + + sender.sendMessage("Took " + ((double) l) / 1000000 + "ms"); /* try {