refactor terrascript into API, loader, and function addons

This commit is contained in:
dfsek
2021-08-08 12:20:26 -07:00
parent 2b142b282f
commit 3594beb406
52 changed files with 243 additions and 267 deletions
@@ -2,7 +2,7 @@ package com.dfsek.terra.addons.terrascript;
import com.dfsek.tectonic.exception.LoadException;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.script.StructureScript;
import com.dfsek.terra.addons.terrascript.script.StructureScriptImpl;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.addon.annotations.Addon;
@@ -36,7 +36,7 @@ public class TerraScriptAddon extends TerraAddon {
event.getPack().getLoader().open("", ".tesf").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) {
try {
StructureScript structureScript = new StructureScript(entry.getValue(), main, structureRegistry, lootRegistry, event.getPack().getRegistryFactory().create());
com.dfsek.terra.addons.terrascript.api.StructureScript structureScript = new StructureScriptImpl(entry.getValue(), main, structureRegistry, lootRegistry, event.getPack().getRegistryFactory().create());
structureRegistry.register(structureScript.getID(), structureScript);
} catch(ParseException e) {
throw new LoadException("Failed to load script: ", e);
@@ -1,30 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
import java.util.ArrayList;
import java.util.List;
public class Cell implements BufferedItem {
private final List<BufferedItem> items = new ArrayList<>();
private String mark = null;
@Override
public void paste(Vector3 origin, World world) {
items.forEach(item -> item.paste(origin.clone(), world));
}
public void add(BufferedItem item) {
items.add(item);
}
public String getMark() {
return mark;
}
public void setMark(String mark) {
this.mark = mark;
}
}
@@ -1,56 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Buffer implementation that directly pastes to the world.
*/
public class DirectBuffer implements Buffer {
private final Vector3 origin;
private final World target;
private final Map<Vector3, String> marks = new LinkedHashMap<>();
public DirectBuffer(Vector3 origin, World target) {
this.origin = origin;
this.target = target;
}
@Override
public void paste(Vector3 origin, Chunk chunk) {
// no-op
}
@Override
public void paste(Vector3 origin, World world) {
// no-op
}
@Override
public Buffer addItem(BufferedItem item, Vector3 location) {
item.paste(origin.clone().add(location), target);
return this;
}
@Override
public Vector3 getOrigin() {
return origin;
}
@Override
public String getMark(Vector3 location) {
return marks.get(location);
}
@Override
public Buffer setMark(String mark, Vector3 location) {
marks.put(location, mark);
return this;
}
}
@@ -1,48 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
public class IntermediateBuffer implements Buffer {
private final Buffer original;
private final Vector3 offset;
public IntermediateBuffer(Buffer original, Vector3 offset) {
this.original = original;
this.offset = offset.clone();
}
@Override
public void paste(Vector3 origin, Chunk chunk) {
// no-op
}
@Override
public void paste(Vector3 origin, World world) {
// no-op
}
@Override
public Buffer addItem(BufferedItem item, Vector3 location) {
return original.addItem(item, location.clone().add(offset));
}
@Override
public Vector3 getOrigin() {
return original.getOrigin().clone().add(offset);
}
@Override
public String getMark(Vector3 location) {
return original.getMark(location.clone().add(offset));
}
@Override
public Buffer setMark(String mark, Vector3 location) {
original.setMark(mark, location.clone().add(offset));
return this;
}
}
@@ -1,68 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
import net.jafama.FastMath;
import java.util.LinkedHashMap;
import java.util.Map;
public class StructureBuffer implements Buffer {
private final Map<Vector3, Cell> bufferedItemMap = new LinkedHashMap<>();
private final Vector3 origin;
private boolean succeeded;
public StructureBuffer(Vector3 origin) {
this.origin = origin;
}
public void paste(Vector3 origin, World world) {
bufferedItemMap.forEach(((vector3, item) -> item.paste(origin.clone().add(vector3), world)));
}
public void paste(Vector3 origin, Chunk chunk) {
bufferedItemMap.forEach(((location, item) -> {
Vector3 current = origin.clone().add(location);
if(FastMath.floorDiv(current.getBlockX(), 16) != chunk.getX() || FastMath.floorDiv(current.getBlockZ(), 16) != chunk.getZ())
return;
item.paste(current, chunk.getWorld());
}));
}
@Override
public Buffer addItem(BufferedItem item, Vector3 location) {
bufferedItemMap.computeIfAbsent(location.clone(), l -> new Cell()).add(item);
return this;
}
@Override
public String getMark(Vector3 location) {
Cell cell = bufferedItemMap.get(location);
if(cell != null) {
return cell.getMark();
}
return null;
}
@Override
public Buffer setMark(String mark, Vector3 location) {
bufferedItemMap.computeIfAbsent(location.clone(), l -> new Cell()).setMark(mark);
return this;
}
public void setSucceeded(boolean succeeded) {
this.succeeded = succeeded;
}
public boolean succeeded() {
return succeeded;
}
@Override
public Vector3 getOrigin() {
return origin.clone();
}
}
@@ -1,38 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer.items;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.properties.base.Properties;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
public class BufferedBlock implements BufferedItem {
private final BlockState data;
private final boolean overwrite;
private final TerraPlugin main;
private final boolean waterlog;
public BufferedBlock(BlockState data, boolean overwrite, TerraPlugin main, boolean waterlog) {
this.data = data;
this.overwrite = overwrite;
this.main = main;
this.waterlog = waterlog;
}
@Override
public void paste(Vector3 origin, World world) {
try {
BlockState current = world.getBlockData(origin);
if(overwrite || current.isAir()) {
if(waterlog && current.has(Properties.WATERLOGGED) && current.getBlockType().isWater()) {
current.set(Properties.WATERLOGGED, true);
}
world.setBlockData(origin, data);
}
} catch(RuntimeException e) {
main.logger().severe("Failed to place block at location " + origin + ": " + e.getMessage());
main.getDebugLogger().stack(e);
}
}
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer.items;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.event.events.world.generation.EntitySpawnEvent;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
public class BufferedEntity implements BufferedItem {
private final EntityType type;
private final TerraPlugin main;
public BufferedEntity(EntityType type, TerraPlugin main) {
this.type = type;
this.main = main;
}
@Override
public void paste(Vector3 origin, World world) {
Entity entity = world.spawnEntity(origin.clone().add(0.5, 0, 0.5), type);
main.getEventManager().callEvent(new EntitySpawnEvent(entity.world().getConfig().getPack(), entity));
}
}
@@ -1,47 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer.items;
import com.dfsek.terra.addons.terrascript.script.StructureScript;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.block.entity.Container;
import com.dfsek.terra.api.event.events.world.generation.LootPopulateEvent;
import com.dfsek.terra.api.structure.LootTable;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
import java.util.Random;
public class BufferedLootApplication implements BufferedItem {
private final LootTable table;
private final TerraPlugin main;
private final StructureScript structure;
public BufferedLootApplication(LootTable table, TerraPlugin main, StructureScript structure) {
this.table = table;
this.main = main;
this.structure = structure;
}
@Override
public void paste(Vector3 origin, World world) {
try {
BlockEntity data = world.getBlockState(origin);
if(!(data instanceof Container)) {
main.logger().severe("Failed to place loot at " + origin + "; block " + data + " is not container.");
return;
}
Container container = (Container) data;
LootPopulateEvent event = new LootPopulateEvent(container, table, world.getConfig().getPack(), structure);
main.getEventManager().callEvent(event);
if(event.isCancelled()) return;
event.getTable().fillInventory(container.getInventory(), new Random(origin.hashCode()));
data.update(false);
} catch(Exception e) {
main.logger().warning("Could not apply loot at " + origin + ": " + e.getMessage());
e.printStackTrace();
}
}
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer.items;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
public class BufferedPulledBlock implements BufferedItem {
private final BlockState data;
public BufferedPulledBlock(BlockState data) {
this.data = data;
}
@Override
public void paste(Vector3 origin, World world) {
Vector3 mutable = origin.clone();
while(mutable.getY() > world.getMinHeight()) {
if(!world.getBlockData(mutable).isAir()) {
world.setBlockData(mutable, data);
break;
}
mutable.subtract(0, 1, 0);
}
}
}
@@ -1,29 +0,0 @@
package com.dfsek.terra.addons.terrascript.buffer.items;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.entity.BlockEntity;
import com.dfsek.terra.api.structure.buffer.BufferedItem;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
public class BufferedStateManipulator implements BufferedItem {
private final TerraPlugin main;
private final String data;
public BufferedStateManipulator(TerraPlugin main, String state) {
this.main = main;
this.data = state;
}
@Override
public void paste(Vector3 origin, World world) {
try {
BlockEntity state = world.getBlockState(origin);
state.applyState(data);
state.update(false);
} catch(Exception e) {
main.logger().warning("Could not apply BlockState at " + origin + ": " + e.getMessage());
e.printStackTrace();
}
}
}
@@ -9,7 +9,7 @@ import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Block;
import com.dfsek.terra.addons.terrascript.parser.lang.Keyword;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.BooleanConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.addons.terrascript.api.lang.ConstantExpression;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.NumericConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.StringConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.keywords.flow.BreakKeyword;
@@ -1,6 +1,7 @@
package com.dfsek.terra.addons.terrascript.parser.lang.constants;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.ConstantExpression;
public class BooleanConstant extends ConstantExpression<Boolean> {
public BooleanConstant(Boolean constant, Position position) {
@@ -1,32 +0,0 @@
package com.dfsek.terra.addons.terrascript.parser.lang.constants;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import java.util.Map;
public abstract class ConstantExpression<T> implements Returnable<T> {
private final T constant;
private final Position position;
public ConstantExpression(T constant, Position position) {
this.constant = constant;
this.position = position;
}
@Override
public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return constant;
}
@Override
public Position getPosition() {
return position;
}
public T getConstant() {
return constant;
}
}
@@ -1,6 +1,7 @@
package com.dfsek.terra.addons.terrascript.parser.lang.constants;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.ConstantExpression;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
public class NumericConstant extends ConstantExpression<Number> {
@@ -1,6 +1,7 @@
package com.dfsek.terra.addons.terrascript.parser.lang.constants;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.ConstantExpression;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
public class StringConstant extends ConstantExpression<String> {
@@ -1,176 +0,0 @@
package com.dfsek.terra.addons.terrascript.script;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.buffer.DirectBuffer;
import com.dfsek.terra.addons.terrascript.buffer.StructureBuffer;
import com.dfsek.terra.addons.terrascript.parser.Parser;
import com.dfsek.terra.addons.terrascript.parser.lang.Block;
import com.dfsek.terra.addons.terrascript.script.builders.BinaryNumberFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.BiomeFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.BlockFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.CheckBlockFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.CheckFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.EntityFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.GetMarkFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.LootFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.PullFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.RandomFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.RecursionsFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.SetMarkFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.StateFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.StructureFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryBooleanFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryNumberFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.UnaryStringFunctionBuilder;
import com.dfsek.terra.addons.terrascript.script.builders.ZeroArgFunctionBuilder;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.LootTable;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import net.jafama.FastMath;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Random;
import java.util.concurrent.ExecutionException;
public class StructureScript implements Structure {
private final Block block;
private final String id;
private final Cache<Vector3, StructureBuffer> cache;
private final TerraPlugin main;
private String tempID;
public StructureScript(InputStream inputStream, TerraPlugin main, Registry<Structure> registry, Registry<LootTable> lootRegistry, Registry<FunctionBuilder<?>> functionRegistry) throws ParseException {
Parser parser;
try {
parser = new Parser(IOUtils.toString(inputStream, Charset.defaultCharset()));
} catch(IOException e) {
throw new RuntimeException(e);
}
functionRegistry.forEach(parser::registerFunction); // Register registry functions.
parser
.registerFunction("block", new BlockFunctionBuilder(main))
.registerFunction("debugBlock", new BlockFunctionBuilder(main))
.registerFunction("check", new CheckFunctionBuilder(main))
.registerFunction("structure", new StructureFunctionBuilder(registry, main))
.registerFunction("randomInt", new RandomFunctionBuilder())
.registerFunction("recursions", new RecursionsFunctionBuilder())
.registerFunction("setMark", new SetMarkFunctionBuilder())
.registerFunction("getMark", new GetMarkFunctionBuilder())
.registerFunction("pull", new PullFunctionBuilder(main))
.registerFunction("loot", new LootFunctionBuilder(main, lootRegistry, this))
.registerFunction("entity", new EntityFunctionBuilder(main))
.registerFunction("getBiome", new BiomeFunctionBuilder(main))
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
.registerFunction("state", new StateFunctionBuilder(main))
.registerFunction("setWaterlog", new UnaryBooleanFunctionBuilder((waterlog, args) -> args.setWaterlog(waterlog)))
.registerFunction("originX", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getX(), Returnable.ReturnType.NUMBER))
.registerFunction("originY", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getY(), Returnable.ReturnType.NUMBER))
.registerFunction("originZ", new ZeroArgFunctionBuilder<Number>(arguments -> arguments.getBuffer().getOrigin().getZ(), Returnable.ReturnType.NUMBER))
.registerFunction("rotation", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().toString(), Returnable.ReturnType.STRING))
.registerFunction("rotationDegrees", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().getDegrees(), Returnable.ReturnType.NUMBER))
.registerFunction("print", new UnaryStringFunctionBuilder(string -> main.getDebugLogger().info("[" + tempID + "] " + string)))
.registerFunction("abs", new UnaryNumberFunctionBuilder(number -> FastMath.abs(number.doubleValue())))
.registerFunction("pow", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.pow(number.doubleValue(), number2.doubleValue())))
.registerFunction("sqrt", new UnaryNumberFunctionBuilder(number -> FastMath.sqrt(number.doubleValue())))
.registerFunction("floor", new UnaryNumberFunctionBuilder(number -> FastMath.floor(number.doubleValue())))
.registerFunction("ceil", new UnaryNumberFunctionBuilder(number -> FastMath.ceil(number.doubleValue())))
.registerFunction("log", new UnaryNumberFunctionBuilder(number -> FastMath.log(number.doubleValue())))
.registerFunction("round", new UnaryNumberFunctionBuilder(number -> FastMath.round(number.doubleValue())))
.registerFunction("sin", new UnaryNumberFunctionBuilder(number -> FastMath.sin(number.doubleValue())))
.registerFunction("cos", new UnaryNumberFunctionBuilder(number -> FastMath.cos(number.doubleValue())))
.registerFunction("tan", new UnaryNumberFunctionBuilder(number -> FastMath.tan(number.doubleValue())))
.registerFunction("asin", new UnaryNumberFunctionBuilder(number -> FastMath.asin(number.doubleValue())))
.registerFunction("acos", new UnaryNumberFunctionBuilder(number -> FastMath.acos(number.doubleValue())))
.registerFunction("atan", new UnaryNumberFunctionBuilder(number -> FastMath.atan(number.doubleValue())))
.registerFunction("max", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.max(number.doubleValue(), number2.doubleValue())))
.registerFunction("min", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.min(number.doubleValue(), number2.doubleValue())));
if(!main.getTerraConfig().isDebugScript()) {
parser.ignoreFunction("debugBlock");
}
block = parser.parse();
this.id = parser.getID();
tempID = id;
this.main = main;
this.cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getStructureCache()).build();
}
@Override
@SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_chunk:" + id)) {
StructureBuffer buffer = computeBuffer(location, world, random, rotation);
buffer.paste(location, chunk);
return buffer.succeeded();
}
}
@SuppressWarnings("try")
public boolean test(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_test:" + id)) {
StructureBuffer buffer = computeBuffer(location, world, random, rotation);
return buffer.succeeded();
}
}
private StructureBuffer computeBuffer(Vector3 location, World world, Random random, Rotation rotation) {
try {
return cache.get(location, () -> {
StructureBuffer buf = new StructureBuffer(location);
buf.setSucceeded(applyBlock(new TerraImplementationArguments(buf, rotation, random, world, 0)));
return buf;
});
} catch(ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
@SuppressWarnings("try")
public boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_recursive:" + id)) {
return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, recursions));
}
}
@Override
@SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_direct:" + id)) {
DirectBuffer buffer = new DirectBuffer(location, world);
return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0));
}
}
@Override
public String getID() {
return id;
}
private boolean applyBlock(TerraImplementationArguments arguments) {
try {
return block.apply(arguments).getLevel() != Block.ReturnLevel.FAIL;
} catch(RuntimeException e) {
main.logger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
main.getDebugLogger().stack(e);
return false;
}
}
}
@@ -0,0 +1,117 @@
package com.dfsek.terra.addons.terrascript.script;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.StructureScript;
import com.dfsek.terra.addons.terrascript.api.TerraImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.buffer.DirectBuffer;
import com.dfsek.terra.addons.terrascript.api.buffer.StructureBuffer;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.parser.Parser;
import com.dfsek.terra.addons.terrascript.parser.lang.Block;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.profiler.ProfileFrame;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.LootTable;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Random;
import java.util.concurrent.ExecutionException;
public class StructureScriptImpl implements StructureScript {
private final Block block;
private final String id;
private final Cache<Vector3, StructureBuffer> cache;
private final TerraPlugin main;
private String tempID;
public StructureScriptImpl(InputStream inputStream, TerraPlugin main, Registry<Structure> registry, Registry<LootTable> lootRegistry, Registry<FunctionBuilder<?>> functionRegistry) throws ParseException {
Parser parser;
try {
parser = new Parser(IOUtils.toString(inputStream, Charset.defaultCharset()));
} catch(IOException e) {
throw new RuntimeException(e);
}
functionRegistry.forEach(parser::registerFunction); // Register registry functions.
block = parser.parse();
this.id = parser.getID();
tempID = id;
this.main = main;
this.cache = CacheBuilder.newBuilder().maximumSize(main.getTerraConfig().getStructureCache()).build();
}
@Override
@SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_chunk:" + id)) {
StructureBuffer buffer = computeBuffer(location, world, random, rotation);
buffer.paste(location, chunk);
return buffer.succeeded();
}
}
@Override
@SuppressWarnings("try")
public boolean test(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_test:" + id)) {
StructureBuffer buffer = computeBuffer(location, world, random, rotation);
return buffer.succeeded();
}
}
private StructureBuffer computeBuffer(Vector3 location, World world, Random random, Rotation rotation) {
try {
return cache.get(location, () -> {
StructureBuffer buf = new StructureBuffer(location);
buf.setSucceeded(applyBlock(new TerraImplementationArguments(buf, rotation, random, world, 0)));
return buf;
});
} catch(ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
@SuppressWarnings("try")
public boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_recursive:" + id)) {
return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, recursions));
}
}
@Override
@SuppressWarnings("try")
public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
try(ProfileFrame ignore = main.getProfiler().profile("terrascript_direct:" + id)) {
DirectBuffer buffer = new DirectBuffer(location, world);
return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0));
}
}
@Override
public String getID() {
return id;
}
private boolean applyBlock(TerraImplementationArguments arguments) {
try {
return block.apply(arguments).getLevel() != Block.ReturnLevel.FAIL;
} catch(RuntimeException e) {
main.logger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
main.getDebugLogger().stack(e);
return false;
}
}
}
@@ -1,53 +0,0 @@
package com.dfsek.terra.addons.terrascript.script;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.world.World;
import java.util.Random;
public class TerraImplementationArguments implements ImplementationArguments {
private final Buffer buffer;
private final Rotation rotation;
private final Random random;
private final World world;
private final int recursions;
private boolean waterlog = false;
public TerraImplementationArguments(Buffer buffer, Rotation rotation, Random random, World world, int recursions) {
this.buffer = buffer;
this.rotation = rotation;
this.random = random;
this.world = world;
this.recursions = recursions;
}
public Buffer getBuffer() {
return buffer;
}
public int getRecursions() {
return recursions;
}
public Random getRandom() {
return random;
}
public Rotation getRotation() {
return rotation;
}
public boolean isWaterlog() {
return waterlog;
}
public void setWaterlog(boolean waterlog) {
this.waterlog = waterlog;
}
public World getWorld() {
return world;
}
}
@@ -1,53 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class BinaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
private final BiFunction<Number, Number, Number> function;
public BinaryNumberFunctionBuilder(BiFunction<Number, Number, Number> function) {
this.function = function;
}
@Override
public Function<Number> build(List<Returnable<?>> argumentList, Position position) {
return new Function<Number>() {
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@SuppressWarnings("unchecked")
@Override
public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, variableMap), ((Returnable<Number>) argumentList.get(1)).apply(implementationArguments, variableMap));
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 2;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0 || position == 1) return Returnable.ReturnType.NUMBER;
return null;
}
}
@@ -1,40 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.BiomeFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class BiomeFunctionBuilder implements FunctionBuilder<BiomeFunction> {
private final TerraPlugin main;
public BiomeFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public BiomeFunction build(List<Returnable<?>> argumentList, Position position) {
return new BiomeFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -1,53 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.BooleanConstant;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.StringConstant;
import com.dfsek.terra.addons.terrascript.script.functions.BlockFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class BlockFunctionBuilder implements FunctionBuilder<BlockFunction> {
private final TerraPlugin main;
public BlockFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public BlockFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
Returnable<Boolean> booleanReturnable = new BooleanConstant(true, position);
if(argumentList.size() == 5) booleanReturnable = (Returnable<Boolean>) argumentList.get(4);
if(argumentList.get(3) instanceof StringConstant) {
return new BlockFunction.Constant((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (StringConstant) argumentList.get(3), booleanReturnable, main, position);
}
return new BlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), booleanReturnable, main, position);
}
@Override
public int argNumber() {
return -1;
}
@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;
case 4:
return Returnable.ReturnType.BOOLEAN;
default:
return null;
}
}
}
@@ -1,33 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.CheckBlockFunction;
import java.util.List;
public class CheckBlockFunctionBuilder implements FunctionBuilder<CheckBlockFunction> {
@SuppressWarnings("unchecked")
@Override
public CheckBlockFunction build(List<Returnable<?>> argumentList, Position position) {
return new CheckBlockFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -1,41 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.CheckFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
private final TerraPlugin main;
public CheckFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public CheckFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new CheckFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -1,43 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.EntityFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class EntityFunctionBuilder implements FunctionBuilder<EntityFunction> {
private final TerraPlugin main;
public EntityFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public EntityFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new EntityFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) 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;
}
}
}
@@ -1,37 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.GetMarkFunction;
import java.util.List;
public class GetMarkFunctionBuilder implements FunctionBuilder<GetMarkFunction> {
public GetMarkFunctionBuilder() {
}
@SuppressWarnings("unchecked")
@Override
public GetMarkFunction build(List<Returnable<?>> argumentList, Position position) {
return new GetMarkFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
}
@Override
public int argNumber() {
return 3;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -1,49 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.StructureScript;
import com.dfsek.terra.addons.terrascript.script.functions.LootFunction;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.LootTable;
import java.util.List;
public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
private final TerraPlugin main;
private final Registry<LootTable> registry;
private final StructureScript script;
public LootFunctionBuilder(TerraPlugin main, Registry<LootTable> registry, StructureScript script) {
this.main = main;
this.registry = registry;
this.script = script;
}
@SuppressWarnings("unchecked")
@Override
public LootFunction build(List<Returnable<?>> argumentList, Position position) {
return new LootFunction(registry, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position, script);
}
@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;
}
}
}
@@ -1,43 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.PullFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class PullFunctionBuilder implements FunctionBuilder<PullFunction> {
private final TerraPlugin main;
public PullFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public PullFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new PullFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) 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;
}
}
}
@@ -1,28 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.RandomFunction;
import java.util.List;
public class RandomFunctionBuilder implements FunctionBuilder<RandomFunction> {
@SuppressWarnings("unchecked")
@Override
public RandomFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new RandomFunction((Returnable<Number>) 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;
}
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.RecursionsFunction;
import java.util.List;
public class RecursionsFunctionBuilder implements FunctionBuilder<RecursionsFunction> {
@Override
public RecursionsFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new RecursionsFunction(position);
}
@Override
public int argNumber() {
return 0;
}
@Override
public Returnable.ReturnType getArgument(int position) {
return null;
}
}
@@ -1,40 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.SetMarkFunction;
import java.util.List;
public class SetMarkFunctionBuilder implements FunctionBuilder<SetMarkFunction> {
public SetMarkFunctionBuilder() {
}
@SuppressWarnings("unchecked")
@Override
public SetMarkFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
return new SetMarkFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), 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;
}
}
}
@@ -1,44 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.StateFunction;
import com.dfsek.terra.api.TerraPlugin;
import java.util.List;
public class StateFunctionBuilder implements FunctionBuilder<StateFunction> {
private final TerraPlugin main;
public StateFunctionBuilder(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public StateFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
return new StateFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) 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;
}
}
}
@@ -1,49 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.script.functions.StructureFunction;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.Structure;
import java.util.List;
import java.util.stream.Collectors;
public class StructureFunctionBuilder implements FunctionBuilder<StructureFunction> {
private final Registry<Structure> registry;
private final TerraPlugin main;
public StructureFunctionBuilder(Registry<Structure> registry, TerraPlugin main) {
this.registry = registry;
this.main = main;
}
@SuppressWarnings("unchecked")
@Override
public StructureFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
if(argumentList.size() < 5) throw new ParseException("Expected rotations", position);
return new StructureFunction((Returnable<Number>) argumentList.remove(0), (Returnable<Number>) argumentList.remove(0), (Returnable<Number>) argumentList.remove(0), (Returnable<String>) argumentList.remove(0),
argumentList.stream().map(item -> ((Returnable<String>) item)).collect(Collectors.toList()), registry, position, main);
}
@Override
public int argNumber() {
return -1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return Returnable.ReturnType.STRING;
}
}
}
@@ -1,55 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public class UnaryBooleanFunctionBuilder implements FunctionBuilder<Function<Void>> {
private final BiConsumer<Boolean, TerraImplementationArguments> function;
public UnaryBooleanFunctionBuilder(BiConsumer<Boolean, TerraImplementationArguments> function) {
this.function = function;
}
@Override
public Function<Void> build(List<Returnable<?>> argumentList, Position position) {
return new Function<Void>() {
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
@SuppressWarnings("unchecked")
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
function.accept(((Returnable<Boolean>) argumentList.get(0)).apply(implementationArguments, variableMap), (TerraImplementationArguments) implementationArguments);
return null;
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.BOOLEAN;
return null;
}
}
@@ -1,52 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import java.util.List;
import java.util.Map;
public class UnaryNumberFunctionBuilder implements FunctionBuilder<Function<Number>> {
private final java.util.function.Function<Number, Number> function;
public UnaryNumberFunctionBuilder(java.util.function.Function<Number, Number> function) {
this.function = function;
}
@Override
public Function<Number> build(List<Returnable<?>> argumentList, Position position) {
return new Function<Number>() {
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@SuppressWarnings("unchecked")
@Override
public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply(((Returnable<Number>) argumentList.get(0)).apply(implementationArguments, variableMap));
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.NUMBER;
return null;
}
}
@@ -1,53 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import java.util.List;
import java.util.Map;
public class UnaryStringFunctionBuilder implements FunctionBuilder<Function<Void>> {
private final java.util.function.Consumer<String> function;
public UnaryStringFunctionBuilder(java.util.function.Consumer<String> function) {
this.function = function;
}
@Override
public Function<Void> build(List<Returnable<?>> argumentList, Position position) {
return new Function<Void>() {
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
@SuppressWarnings("unchecked")
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
function.accept(((Returnable<String>) argumentList.get(0)).apply(implementationArguments, variableMap));
return null;
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 1;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return Returnable.ReturnType.STRING;
return null;
}
}
@@ -1,53 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.builders;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.FunctionBuilder;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import java.util.List;
import java.util.Map;
public class ZeroArgFunctionBuilder<T> implements FunctionBuilder<Function<T>> {
private final java.util.function.Function<TerraImplementationArguments, T> function;
private final Returnable.ReturnType type;
public ZeroArgFunctionBuilder(java.util.function.Function<TerraImplementationArguments, T> function, Returnable.ReturnType type) {
this.function = function;
this.type = type;
}
@Override
public Function<T> build(List<Returnable<?>> argumentList, Position position) {
return new Function<T>() {
@Override
public ReturnType returnType() {
return type;
}
@Override
public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return function.apply((TerraImplementationArguments) implementationArguments);
}
@Override
public Position getPosition() {
return position;
}
};
}
@Override
public int argNumber() {
return 0;
}
@Override
public Returnable.ReturnType getArgument(int position) {
if(position == 0) return type;
return null;
}
}
@@ -1,56 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import net.jafama.FastMath;
import java.util.Map;
public class BiomeFunction implements Function<String> {
private final TerraPlugin main;
private final Returnable<Number> x, y, z;
private final Position position;
public BiomeFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.main = main;
this.x = x;
this.y = y;
this.z = z;
this.position = position;
}
@Override
public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
BiomeProvider grid = arguments.getWorld().getBiomeProvider();
return grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))), arguments.getWorld().getSeed()).getID();
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;
}
}
@@ -1,83 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.items.BufferedBlock;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.StringConstant;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.HashMap;
import java.util.Map;
public class BlockFunction implements Function<Void> {
protected final Returnable<Number> x, y, z;
protected final Returnable<String> blockData;
protected final TerraPlugin main;
private final Map<String, BlockState> data = new HashMap<>();
private final Returnable<Boolean> overwrite;
private final Position position;
public BlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> blockData, Returnable<Boolean> overwrite, TerraPlugin main, Position position) {
this.x = x;
this.y = y;
this.z = z;
this.blockData = blockData;
this.overwrite = overwrite;
this.main = main;
this.position = position;
}
void setBlock(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap, TerraImplementationArguments arguments, BlockState rot) {
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments, variableMap), main, arguments.isWaterlog()), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())));
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
BlockState rot = getBlockState(implementationArguments, variableMap).clone();
setBlock(implementationArguments, variableMap, arguments, rot);
return null;
}
protected BlockState getBlockState(ImplementationArguments arguments, Map<String, Variable<?>> variableMap) {
return data.computeIfAbsent(blockData.apply(arguments, variableMap), main.getWorldHandle()::createBlockData);
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
public static class Constant extends BlockFunction {
private final BlockState state;
public Constant(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, StringConstant blockData, Returnable<Boolean> overwrite, TerraPlugin main, Position position) {
super(x, y, z, blockData, overwrite, main, position);
this.state = main.getWorldHandle().createBlockData(blockData.getConstant());
}
@Override
protected BlockState getBlockState(ImplementationArguments arguments, Map<String, Variable<?>> variableMap) {
return state;
}
}
}
@@ -1,51 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class CheckBlockFunction implements Function<String> {
private final Returnable<Number> x, y, z;
private final Position position;
public CheckBlockFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.x = x;
this.y = y;
this.z = z;
this.position = position;
}
@Override
public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
String data = arguments.getWorld().getBlockData(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())))).getAsString();
if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties
else return data;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;
}
}
@@ -1,80 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.generator.SamplerCache;
import net.jafama.FastMath;
import java.util.Map;
public class CheckFunction implements Function<String> {
private final TerraPlugin main;
private final Returnable<Number> x, y, z;
private final Position position;
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.main = main;
this.x = x;
this.y = y;
this.z = z;
this.position = position;
}
@Override
public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
Vector3 location = arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())));
return apply(location, arguments.getWorld());
}
private String apply(Vector3 vector, World world) {
int y = vector.getBlockY();
if(y >= world.getMaxHeight() || y < 0) return "AIR";
SamplerCache cache = world.getConfig().getSamplerCache();
double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), cache);
if(comp > 0) return "LAND"; // If noise val is greater than zero, location will always be land.
//BiomeProvider provider = tw.getBiomeProvider();
//TerraBiome b = provider.getBiome(vector.getBlockX(), vector.getBlockZ());
/*if(vector.getY() > c.getSeaLevel())*/
return "AIR"; // Above sea level
//return "OCEAN"; // Below sea level
}
private double sample(int x, int y, int z, SamplerCache cache) {
int cx = FastMath.floorDiv(x, 16);
int cz = FastMath.floorDiv(z, 16);
return cache.get(x, z).sample(x - (cx << 4), y, z - (cz << 4));
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;
}
}
@@ -1,57 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.items.BufferedEntity;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.entity.EntityType;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import java.util.Map;
public class EntityFunction implements Function<Void> {
private final EntityType data;
private final Returnable<Number> x, y, z;
private final Position position;
private final TerraPlugin main;
public EntityFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) throws ParseException {
this.position = position;
this.main = main;
if(!(data instanceof ConstantExpression)) throw new ParseException("Entity data must be constant", data.getPosition());
this.data = main.getWorldHandle().getEntity(((ConstantExpression<String>) data).getConstant());
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().addItem(new BufferedEntity(data, main), new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
@@ -1,46 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class GetMarkFunction implements Function<String> {
private final Returnable<Number> x, y, z;
private final Position position;
public GetMarkFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
this.position = position;
this.x = x;
this.y = y;
this.z = z;
}
@Override
public String apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
String mark = arguments.getBuffer().getMark(new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments, variableMap).doubleValue()), FastMath.floorToInt(xz.getZ())));
return mark == null ? "" : mark;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.STRING;
}
}
@@ -1,68 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.items.BufferedLootApplication;
import com.dfsek.terra.addons.terrascript.script.StructureScript;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.LootTable;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class LootFunction implements Function<Void> {
private final Registry<LootTable> registry;
private final Returnable<String> data;
private final Returnable<Number> x, y, z;
private final Position position;
private final TerraPlugin main;
private final StructureScript script;
public LootFunction(Registry<LootTable> registry, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position, StructureScript script) {
this.registry = registry;
this.position = position;
this.data = data;
this.x = x;
this.y = y;
this.z = z;
this.main = main;
this.script = script;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
String id = data.apply(implementationArguments, variableMap);
LootTable table = registry.get(id);
if(table == null) {
main.logger().severe("No such loot table " + id);
return null;
}
arguments.getBuffer().addItem(new BufferedLootApplication(table, main, script), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
@@ -1,57 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.exception.ParseException;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.items.BufferedPulledBlock;
import com.dfsek.terra.addons.terrascript.parser.lang.constants.ConstantExpression;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class PullFunction implements Function<Void> {
private final BlockState data;
private final Returnable<Number> x, y, z;
private final Position position;
public PullFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> 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<String>) data).getConstant());
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
BlockState rot = data.clone();
RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse());
arguments.getBuffer().addItem(new BufferedPulledBlock(rot), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
@@ -1,36 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import java.util.Map;
public class RandomFunction implements Function<Integer> {
private final Returnable<Number> numberReturnable;
private final Position position;
public RandomFunction(Returnable<Number> numberReturnable, Position position) {
this.numberReturnable = numberReturnable;
this.position = position;
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@Override
public Integer apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return ((TerraImplementationArguments) implementationArguments).getRandom().nextInt(numberReturnable.apply(implementationArguments, variableMap).intValue());
}
@Override
public Position getPosition() {
return position;
}
}
@@ -1,32 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import java.util.Map;
public class RecursionsFunction implements Function<Number> {
private final Position position;
public RecursionsFunction(Position position) {
this.position = position;
}
@Override
public ReturnType returnType() {
return ReturnType.NUMBER;
}
@Override
public Number apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
return ((TerraImplementationArguments) implementationArguments).getRecursions();
}
@Override
public Position getPosition() {
return position;
}
}
@@ -1,49 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class SetMarkFunction implements Function<Void> {
private final Returnable<Number> x, y, z;
private final Position position;
private final Returnable<String> mark;
public SetMarkFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> mark, Position position) {
this.position = position;
this.mark = mark;
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().setMark(mark.apply(implementationArguments, variableMap), new Vector3(FastMath.floorToInt(xz.getX()), FastMath.floorToInt(y.apply(implementationArguments, variableMap).doubleValue()), FastMath.floorToInt(xz.getZ())));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
@@ -1,52 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.items.BufferedStateManipulator;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.Map;
public class StateFunction implements Function<Void> {
private final Returnable<String> data;
private final Returnable<Number> x, y, z;
private final Position position;
private final TerraPlugin main;
public StateFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) {
this.position = position;
this.main = main;
this.data = data;
this.x = x;
this.y = y;
this.z = z;
}
@Override
public Void apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
arguments.getBuffer().addItem(new BufferedStateManipulator(main, data.apply(implementationArguments, variableMap)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())));
return null;
}
@Override
public Position getPosition() {
return position;
}
@Override
public ReturnType returnType() {
return ReturnType.VOID;
}
}
@@ -1,82 +0,0 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.terra.addons.terrascript.api.Function;
import com.dfsek.terra.addons.terrascript.api.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.api.Position;
import com.dfsek.terra.addons.terrascript.api.lang.Returnable;
import com.dfsek.terra.addons.terrascript.api.lang.Variable;
import com.dfsek.terra.addons.terrascript.buffer.IntermediateBuffer;
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.vector.Vector2;
import com.dfsek.terra.api.vector.Vector3;
import net.jafama.FastMath;
import java.util.List;
import java.util.Map;
public class StructureFunction implements Function<Boolean> {
private final Registry<Structure> registry;
private final Returnable<String> id;
private final Returnable<Number> x, y, z;
private final Position position;
private final TerraPlugin main;
private final List<Returnable<String>> rotations;
public StructureFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> id, List<Returnable<String>> rotations, Registry<Structure> 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;
this.rotations = rotations;
}
@Override
public ReturnType returnType() {
return ReturnType.BOOLEAN;
}
@Override
public Boolean apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
if(arguments.getRecursions() > main.getTerraConfig().getMaxRecursion())
throw new RuntimeException("Structure recursion too deep: " + arguments.getRecursions());
Vector2 xz = new Vector2(x.apply(implementationArguments, variableMap).doubleValue(), z.apply(implementationArguments, variableMap).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation());
String app = id.apply(implementationArguments, variableMap);
Structure script = registry.get(app);
if(script == null) {
main.logger().severe("No such structure " + app);
return null;
}
Rotation rotation1;
String rotString = rotations.get(arguments.getRandom().nextInt(rotations.size())).apply(implementationArguments, variableMap);
try {
rotation1 = Rotation.valueOf(rotString);
} catch(IllegalArgumentException e) {
main.logger().severe("Invalid rotation " + rotString);
return null;
}
Vector3 offset = new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ()));
return script.generate(new IntermediateBuffer(arguments.getBuffer(), offset), arguments.getWorld(), arguments.getRandom(), arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
}
@Override
public Position getPosition() {
return position;
}
}