From 5028582198407694b8e75a9e66edc7efde49a1dd Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 16 Mar 2021 21:04:56 -0700 Subject: [PATCH] add smart waterlog --- .../terra/api/platform/block/BlockType.java | 2 + .../structures/script/StructureScript.java | 2 + .../script/TerraImplementationArguments.java | 9 +++ .../builders/UnaryBooleanFunctionBuilder.java | 55 +++++++++++++++++++ .../script/functions/BlockFunction.java | 2 +- .../structure/buffer/items/BufferedBlock.java | 11 +++- .../world/block/BukkitBlockTypeAndItem.java | 5 ++ .../fabric/world/block/FabricBlockType.java | 6 ++ .../java/com/dfsek/terra/platform/Data.java | 5 ++ 9 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/api/structures/script/builders/UnaryBooleanFunctionBuilder.java diff --git a/common/src/main/java/com/dfsek/terra/api/platform/block/BlockType.java b/common/src/main/java/com/dfsek/terra/api/platform/block/BlockType.java index d7c6c160d..0703f02f1 100644 --- a/common/src/main/java/com/dfsek/terra/api/platform/block/BlockType.java +++ b/common/src/main/java/com/dfsek/terra/api/platform/block/BlockType.java @@ -6,4 +6,6 @@ public interface BlockType extends Handle { BlockData getDefaultData(); boolean isSolid(); + + boolean isWater(); } 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 8ceb1bf28..c06d3d813 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 @@ -21,6 +21,7 @@ import com.dfsek.terra.api.structures.script.builders.RecursionsFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.SetMarkFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.StateFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder; +import com.dfsek.terra.api.structures.script.builders.UnaryBooleanFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.UnaryNumberFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.UnaryStringFunctionBuilder; import com.dfsek.terra.api.structures.script.builders.ZeroArgFunctionBuilder; @@ -71,6 +72,7 @@ public class StructureScript { .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(arguments -> arguments.getBuffer().getOrigin().getX(), Returnable.ReturnType.NUMBER)) .registerFunction("originY", new ZeroArgFunctionBuilder(arguments -> arguments.getBuffer().getOrigin().getY(), Returnable.ReturnType.NUMBER)) .registerFunction("originZ", new ZeroArgFunctionBuilder(arguments -> arguments.getBuffer().getOrigin().getZ(), Returnable.ReturnType.NUMBER)) diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/TerraImplementationArguments.java b/common/src/main/java/com/dfsek/terra/api/structures/script/TerraImplementationArguments.java index 4183bc583..6d80871ea 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/script/TerraImplementationArguments.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/TerraImplementationArguments.java @@ -11,6 +11,7 @@ public class TerraImplementationArguments implements ImplementationArguments { private final Rotation rotation; private final Random random; private final int recursions; + private boolean waterlog = false; public TerraImplementationArguments(Buffer buffer, Rotation rotation, Random random, int recursions) { this.buffer = buffer; @@ -34,4 +35,12 @@ public class TerraImplementationArguments implements ImplementationArguments { public Rotation getRotation() { return rotation; } + + public boolean isWaterlog() { + return waterlog; + } + + public void setWaterlog(boolean waterlog) { + this.waterlog = waterlog; + } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/builders/UnaryBooleanFunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/UnaryBooleanFunctionBuilder.java new file mode 100644 index 000000000..add26248e --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/builders/UnaryBooleanFunctionBuilder.java @@ -0,0 +1,55 @@ +package com.dfsek.terra.api.structures.script.builders; + +import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments; +import com.dfsek.terra.api.structures.parser.lang.Returnable; +import com.dfsek.terra.api.structures.parser.lang.functions.Function; +import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; +import com.dfsek.terra.api.structures.parser.lang.variables.Variable; +import com.dfsek.terra.api.structures.script.TerraImplementationArguments; +import com.dfsek.terra.api.structures.tokenizer.Position; + +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +public class UnaryBooleanFunctionBuilder implements FunctionBuilder> { + + private final BiConsumer function; + + public UnaryBooleanFunctionBuilder(BiConsumer function) { + this.function = function; + } + + @Override + public Function build(List> argumentList, Position position) { + return new Function() { + @Override + public ReturnType returnType() { + return ReturnType.VOID; + } + + @SuppressWarnings("unchecked") + @Override + public Void apply(ImplementationArguments implementationArguments, Map> variableMap) { + function.accept(((Returnable) 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; + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java index cf9c07ef5..6f9b0d54c 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/script/functions/BlockFunction.java @@ -51,7 +51,7 @@ public class BlockFunction implements Function { RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateBlockData(rot, arguments.getRotation().inverse()); - arguments.getBuffer().addItem(new BufferedBlock(rot, overwrite.apply(implementationArguments, variableMap), main), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ())).toLocation(arguments.getBuffer().getOrigin().getWorld())); + 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())).toLocation(arguments.getBuffer().getOrigin().getWorld())); return null; } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedBlock.java b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedBlock.java index efb706ea9..9507edd15 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedBlock.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/items/BufferedBlock.java @@ -4,23 +4,30 @@ import com.dfsek.terra.api.TerraPlugin; 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.data.Waterlogged; public class BufferedBlock implements BufferedItem { private final BlockData data; private final boolean overwrite; private final TerraPlugin main; + private final boolean waterlog; - public BufferedBlock(BlockData data, boolean overwrite, TerraPlugin main) { + public BufferedBlock(BlockData data, boolean overwrite, TerraPlugin main, boolean waterlog) { this.data = data; this.overwrite = overwrite; this.main = main; + this.waterlog = waterlog; } @Override public void paste(Location origin) { Block block = origin.getBlock(); try { - if(overwrite || block.isEmpty()) block.setBlockData(data, false); + if(overwrite || block.isEmpty()) { + if(waterlog && data instanceof Waterlogged && block.getBlockData().getBlockType().isWater()) + ((Waterlogged) data).setWaterlogged(true); + block.setBlockData(data, false); + } } catch(RuntimeException e) { main.logger().severe("Failed to place block at location " + origin + ": " + e.getMessage()); main.getDebugLogger().stack(e); diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/BukkitBlockTypeAndItem.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/BukkitBlockTypeAndItem.java index aeafa9823..5b3e0767c 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/BukkitBlockTypeAndItem.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/world/block/BukkitBlockTypeAndItem.java @@ -29,6 +29,11 @@ public class BukkitBlockTypeAndItem implements BlockType, Item { return delegate.isSolid(); } + @Override + public boolean isWater() { + return delegate == Material.WATER; + } + @Override public ItemStack newItemStack(int amount) { return BukkitAdapter.adapt(new org.bukkit.inventory.ItemStack(delegate, amount)); diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockType.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockType.java index ae72e4caa..26427bb2f 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockType.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlockType.java @@ -4,6 +4,7 @@ import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.fabric.world.FabricAdapter; import net.minecraft.block.Block; +import net.minecraft.block.Blocks; public class FabricBlockType implements BlockType { private final Block delegate; @@ -27,6 +28,11 @@ public class FabricBlockType implements BlockType { return delegate.getDefaultState().isOpaque(); } + @Override + public boolean isWater() { + return delegate == Blocks.WATER; + } + @Override public int hashCode() { return delegate.hashCode(); diff --git a/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java b/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java index f1c845ab0..2267b7f91 100644 --- a/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java +++ b/platforms/region/src/main/java/com/dfsek/terra/platform/Data.java @@ -97,4 +97,9 @@ public class Data implements BlockData, BlockType { public boolean isSolid() { return false; } + + @Override + public boolean isWater() { + return false; + } }