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 5eeae4c5c..743e94e37 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.script.builders.BlockFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.CheckFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.GetMarkFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.MarkFunctionBuilder; +import com.dfsek.terra.api.structures.script.builders.PullFunctionBuilder; 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; @@ -38,7 +39,8 @@ public class StructureScript { .addFunction("randomInt", new RandomFunctionBuilder()) .addFunction("recursions", new RecursionsFunctionBuilder()) .addFunction("setMark", new MarkFunctionBuilder()) - .addFunction("getMark", new GetMarkFunctionBuilder()); + .addFunction("getMark", new GetMarkFunctionBuilder()) + .addFunction("pull", new PullFunctionBuilder(main)); try { block = parser.parse(); diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/PullFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/PullFunctionBuilder.java new file mode 100644 index 000000000..0c5ab641d --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/PullFunctionBuilder.java @@ -0,0 +1,43 @@ +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.PullFunction; +import com.dfsek.terra.api.structures.tokenizer.Position; + +import java.util.List; + +public class PullFunctionBuilder implements FunctionBuilder { + private final TerraPlugin main; + + public PullFunctionBuilder(TerraPlugin main) { + this.main = main; + } + + @SuppressWarnings("unchecked") + @Override + public PullFunction build(List> argumentList, Position position) throws ParseException { + return new PullFunction((Returnable) argumentList.get(0), (Returnable) argumentList.get(1), (Returnable) argumentList.get(2), (Returnable) argumentList.get(3), main, position); + } + + @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/PullFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/PullFunction.java new file mode 100644 index 000000000..52858215a --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/PullFunction.java @@ -0,0 +1,58 @@ +package com.dfsek.terra.api.structures.script.functions; + +import com.dfsek.terra.api.math.vector.Vector2; +import com.dfsek.terra.api.math.vector.Vector3; +import com.dfsek.terra.api.platform.TerraPlugin; +import com.dfsek.terra.api.platform.block.BlockData; +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.constants.ConstantExpression; +import com.dfsek.terra.api.structures.parser.lang.functions.Function; +import com.dfsek.terra.api.structures.structure.Rotation; +import com.dfsek.terra.api.structures.structure.RotationUtil; +import com.dfsek.terra.api.structures.structure.buffer.Buffer; +import com.dfsek.terra.api.structures.structure.buffer.items.BufferedPulledBlock; +import com.dfsek.terra.api.structures.tokenizer.Position; +import net.jafama.FastMath; + +public class PullFunction implements Function { + private final BlockData data; + private final Returnable x, y, z; + private final Position position; + + public PullFunction(Returnable x, Returnable y, Returnable z, Returnable data, TerraPlugin main, Position position) throws ParseException { + this.position = position; + if(!(data instanceof ConstantExpression)) throw new ParseException("Block data must be constant", data.getPosition()); + + this.data = main.getWorldHandle().createBlockData(((ConstantExpression) data).getConstant()); + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public String name() { + return "pull"; + } + + @Override + public Void apply(Buffer buffer, Rotation rotation, int recursions) { + Vector2 xz = new Vector2(x.apply(buffer, rotation, recursions).doubleValue(), z.apply(buffer, rotation, recursions).doubleValue()); + + RotationUtil.rotateVector(xz, rotation); + BlockData rot = data.clone(); + RotationUtil.rotateBlockData(rot, rotation.inverse()); + buffer.addItem(new BufferedPulledBlock(rot), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(buffer, rotation, recursions).intValue(), FastMath.roundToInt(xz.getZ()))); + return null; + } + + @Override + public Position getPosition() { + return position; + } + + @Override + public ReturnType returnType() { + return ReturnType.VOID; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedPulledBlock.java b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedPulledBlock.java new file mode 100644 index 000000000..8132a53a8 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedPulledBlock.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.api.structures.structure.buffer.items; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.block.Block; +import com.dfsek.terra.api.platform.block.BlockData; +import com.dfsek.terra.api.platform.block.BlockFace; + +public class BufferedPulledBlock implements BufferedItem { + private final BlockData data; + + public BufferedPulledBlock(BlockData data) { + this.data = data; + } + + @Override + public void paste(Location origin) { + Block pos = origin.getBlock(); + while(pos.getY() > 0) { + if(!pos.isEmpty()) { + pos.setBlockData(data, false); + break; + } + pos = pos.getRelative(BlockFace.DOWN); + } + } +}