diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java index 4f5df7e6c..1486eed05 100644 --- a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.flora.flora.gen; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; + import net.jafama.FastMath; import java.util.ArrayList; @@ -54,9 +56,9 @@ public class TerraFlora implements Structure { }); } - private void test(EnumSet faces, Direction f, Vector3 b, WritableWorld world) { + private void test(EnumSet faces, Direction f, Vector3Int b, WritableWorld world) { if(testRotation.contains( - world.getBlockState(b.getBlockX() + f.getModX(), b.getBlockY() + f.getModY(), b.getBlockZ() + f.getModZ()).getBlockType())) + world.getBlockState(b.getX() + f.getModX(), b.getY() + f.getModY(), b.getZ() + f.getModZ()).getBlockType())) faces.add(f); } @@ -64,7 +66,7 @@ public class TerraFlora implements Structure { return layers.get(FastMath.max(FastMath.min(layer, layers.size() - 1), 0)); } - private EnumSet getFaces(Vector3 b, WritableWorld world) { + private EnumSet getFaces(Vector3Int b, WritableWorld world) { EnumSet faces = EnumSet.noneOf(Direction.class); test(faces, Direction.NORTH, b, world); test(faces, Direction.SOUTH, b, world); @@ -79,12 +81,12 @@ public class TerraFlora implements Structure { } @Override - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { boolean doRotation = testRotation.size() > 0; int size = layers.size(); int c = ceiling ? -1 : 1; - EnumSet faces = doRotation ? getFaces(location.clone().add(0, c, 0), world) : EnumSet.noneOf(Direction.class); + EnumSet faces = doRotation ? getFaces(location.mutable().add(0, c, 0).immutable(), world) : EnumSet.noneOf(Direction.class); if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid. for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor @@ -93,7 +95,7 @@ public class TerraFlora implements Structure { location.getZ(), world.getSeed()).clone(); if(doRotation) { Direction oneFace = new ArrayList<>(faces).get( - new Random(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face. + new Random(location.getX() ^ location.getZ()).nextInt(faces.size())); // Get random face. data.setIfPresent(Properties.DIRECTION, oneFace.opposite()) .setIfPresent(Properties.NORTH, faces.contains(Direction.NORTH)) @@ -101,7 +103,7 @@ public class TerraFlora implements Structure { .setIfPresent(Properties.EAST, faces.contains(Direction.EAST)) .setIfPresent(Properties.WEST, faces.contains(Direction.WEST)); } - world.setBlockState(location.clone().add(0, i + c, 0), data, physics); + world.setBlockState(location.mutable().add(0, i + c, 0).immutable(), data, physics); } return true; } diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java index cf58bca9f..78d283579 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.ore.ores; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; + import net.jafama.FastMath; import java.util.Map; @@ -40,50 +42,40 @@ public class VanillaOre implements Structure { } @Override - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation) { - generate(location, world, random); - return true; - } + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + int centerX = location.getX(); + int centerZ = location.getZ(); + int centerY = location.getY(); - @Override - public String getID() { - return null; - } - public void generate(Vector3 location, WritableWorld world, Random random) { - int centerX = location.getBlockX(); - int centerZ = location.getBlockZ(); - int centerY = location.getBlockY(); - - float f = random.nextFloat() * (float) Math.PI; - + double d1 = centerX + 8 + FastMath.sin(f) * size / 8.0F; double d2 = centerX + 8 - FastMath.sin(f) * size / 8.0F; double d3 = centerZ + 8 + FastMath.cos(f) * size / 8.0F; double d4 = centerZ + 8 - FastMath.cos(f) * size / 8.0F; - + double d5 = centerY + random.nextInt(3) - 2D; double d6 = centerY + random.nextInt(3) - 2D; - + for(int i = 0; i < size; i++) { float iFactor = (float) i / (float) size; - + double d10 = random.nextDouble() * size / 16.0D; double d11 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0; double d12 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0; - + int xStart = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor - d11 / 2.0D)); int yStart = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor - d12 / 2.0D)); int zStart = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor - d11 / 2.0D)); - + int xEnd = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor + d11 / 2.0D)); int yEnd = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor + d12 / 2.0D)); int zEnd = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor + d11 / 2.0D)); - + for(int x = xStart; x <= xEnd; x++) { double d13 = (x + 0.5D - (d1 + (d2 - d1) * iFactor)) / (d11 / 2.0D); - + if(d13 * d13 < 1.0D) { for(int y = yStart; y <= yEnd; y++) { double d14 = (y + 0.5D - (d5 + (d6 - d5) * iFactor)) / (d12 / 2.0D); @@ -101,6 +93,12 @@ public class VanillaOre implements Structure { } } } + return true; + } + + @Override + public String getID() { + return null; } public BlockState getMaterial(BlockType replace) { diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java index 6fd0c7ca8..3cd7c8f7e 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -17,6 +17,7 @@ import com.dfsek.terra.api.util.PopulationUtil; import com.dfsek.terra.api.util.Rotation; import com.dfsek.terra.api.util.StringIdentifiable; import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; import com.dfsek.terra.api.world.chunk.generation.ProtoWorld; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; @@ -56,7 +57,7 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab .getSuitableCoordinates(column) .forEach(y -> feature.getStructure(world, tx, y, tz) - .generate(new Vector3(tx, y, tz), + .generate(Vector3Int.of(tx, y, tz), world, new Random(PopulationUtil.getCarverChunkSeed( world.centerChunkX(), diff --git a/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java b/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java index cb6e60735..e9a1f6c8e 100644 --- a/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java +++ b/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java @@ -3,7 +3,7 @@ package com.dfsek.terra.addons.palette.shortcut.block; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.Rotation; -import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; import com.dfsek.terra.api.world.WritableWorld; import java.util.Random; @@ -17,7 +17,7 @@ public class SingletonStructure implements Structure { } @Override - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { world.setBlockState(location, blockState); return true; } diff --git a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java index 27873022b..174c84e23 100644 --- a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java +++ b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java @@ -9,12 +9,11 @@ package com.dfsek.terra.addons.sponge; import java.util.Random; -import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.Rotation; -import com.dfsek.terra.api.util.vector.Vector3; import com.dfsek.terra.api.util.vector.integer.Vector2Int; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; import com.dfsek.terra.api.world.WritableWorld; @@ -30,10 +29,10 @@ public class SpongeStructure implements Structure { } @Override - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation) { - int bX = location.getBlockX(); - int bY = location.getBlockY(); - int bZ = location.getBlockZ(); + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + int bX = location.getX(); + int bY = location.getY(); + int bZ = location.getZ(); for(int x = 0; x < blocks.length; x++) { for(int z = 0; z < blocks[x].length; z++) { Vector2Int r = Vector2Int.of(x, z).rotate(rotation); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/buffer/items/BufferedLootApplication.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/buffer/items/BufferedLootApplication.java deleted file mode 100644 index abe99ff1a..000000000 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/buffer/items/BufferedLootApplication.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2020-2021 Polyhedral Development - * - * The Terra Core Addons are licensed under the terms of the MIT License. For more details, - * reference the LICENSE file in this module's root directory. - */ - -package com.dfsek.terra.addons.terrascript.buffer.items; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Random; - -import com.dfsek.terra.addons.terrascript.script.StructureScript; -import com.dfsek.terra.api.Platform; -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.util.vector.Vector3; -import com.dfsek.terra.api.world.WritableWorld; - - -public class BufferedLootApplication implements BufferedItem { - private static final Logger LOGGER = LoggerFactory.getLogger(BufferedLootApplication.class); - private final LootTable table; - private final Platform platform; - private final StructureScript structure; - - public BufferedLootApplication(LootTable table, Platform platform, StructureScript structure) { - this.table = table; - this.platform = platform; - this.structure = structure; - } - - @Override - public void paste(Vector3 origin, WritableWorld world) { - try { - BlockEntity data = world.getBlockEntity(origin); - if(!(data instanceof Container container)) { - LOGGER.error("Failed to place loot at {}; block {} is not a container", origin, data); - return; - } - - LootPopulateEvent event = new LootPopulateEvent(container, table, world.getPack(), structure); - platform.getEventManager().callEvent(event); - if(event.isCancelled()) return; - - event.getTable().fillInventory(container.getInventory(), new Random(origin.hashCode())); - data.update(false); - } catch(Exception e) { - LOGGER.error("Could not apply loot at {}", origin, e); - e.printStackTrace(); - } - } -} diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java index 03b770032..72ea4c62c 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java @@ -7,8 +7,8 @@ package com.dfsek.terra.addons.terrascript.script; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; + import net.jafama.FastMath; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; @@ -18,7 +18,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Random; -import java.util.concurrent.ExecutionException; import com.dfsek.terra.addons.terrascript.parser.Parser; import com.dfsek.terra.addons.terrascript.parser.lang.Block; @@ -46,10 +45,7 @@ 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.buffers.DirectBuffer; -import com.dfsek.terra.api.structure.buffer.buffers.StructureBuffer; import com.dfsek.terra.api.util.Rotation; -import com.dfsek.terra.api.util.vector.Vector3; import com.dfsek.terra.api.world.WritableWorld; @@ -57,7 +53,6 @@ public class StructureScript implements Structure { private static final Logger LOGGER = LoggerFactory.getLogger(StructureScript.class); private final Block block; private final String id; - private final Cache cache; private final Platform platform; @SuppressWarnings("rawtypes") @@ -89,11 +84,11 @@ public class StructureScript implements Structure { .registerFunction("getBlock", new CheckBlockFunctionBuilder()) .registerFunction("state", new StateFunctionBuilder(platform)) .registerFunction("setWaterlog", new UnaryBooleanFunctionBuilder((waterlog, args) -> args.setWaterlog(waterlog))) - .registerFunction("originX", new ZeroArgFunctionBuilder(arguments -> arguments.getBuffer().getOrigin().getX(), + .registerFunction("originX", new ZeroArgFunctionBuilder(arguments -> arguments.getOrigin().getX(), Returnable.ReturnType.NUMBER)) - .registerFunction("originY", new ZeroArgFunctionBuilder(arguments -> arguments.getBuffer().getOrigin().getY(), + .registerFunction("originY", new ZeroArgFunctionBuilder(arguments -> arguments.getOrigin().getY(), Returnable.ReturnType.NUMBER)) - .registerFunction("originZ", new ZeroArgFunctionBuilder(arguments -> arguments.getBuffer().getOrigin().getZ(), + .registerFunction("originZ", new ZeroArgFunctionBuilder(arguments -> arguments.getOrigin().getZ(), Returnable.ReturnType.NUMBER)) .registerFunction("rotation", new ZeroArgFunctionBuilder<>(arguments -> arguments.getRotation().toString(), Returnable.ReturnType.STRING)) @@ -126,34 +121,19 @@ public class StructureScript implements Structure { block = parser.parse(); this.platform = platform; - this.cache = CacheBuilder.newBuilder().maximumSize(platform.getTerraConfig().getStructureCache()).build(); } @Override @SuppressWarnings("try") - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) { - DirectBuffer buffer = new DirectBuffer(location, world); - return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, 0)); + return applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0)); } } - public boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation, int recursions) { + public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation, int recursions) { try(ProfileFrame ignore = platform.getProfiler().profile("terrascript_direct:" + id)) { - DirectBuffer buffer = new DirectBuffer(location, world); - return applyBlock(new TerraImplementationArguments(buffer, rotation, random, world, recursions)); - } - } - - private StructureBuffer computeBuffer(Vector3 location, WritableWorld 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); + return applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions)); } } @@ -161,7 +141,7 @@ public class StructureScript implements Structure { try { return block.apply(arguments).getLevel() != Block.ReturnLevel.FAIL; } catch(RuntimeException e) { - LOGGER.error("Failed to generate structure at {}", arguments.getBuffer().getOrigin(), e); + LOGGER.error("Failed to generate structure at {}", arguments.getOrigin(), e); return false; } } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java index 627b9d5c3..3d14518bd 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java @@ -7,32 +7,32 @@ package com.dfsek.terra.addons.terrascript.script; +import java.util.HashMap; +import java.util.Map; import java.util.Random; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; -import com.dfsek.terra.api.structure.buffer.Buffer; import com.dfsek.terra.api.util.Rotation; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; import com.dfsek.terra.api.world.WritableWorld; public class TerraImplementationArguments implements ImplementationArguments { - private final Buffer buffer; private final Rotation rotation; private final Random random; private final WritableWorld world; + private final Map marks = new HashMap<>(); private final int recursions; private boolean waterlog = false; + private final Vector3Int origin; - public TerraImplementationArguments(Buffer buffer, Rotation rotation, Random random, WritableWorld world, int recursions) { - this.buffer = buffer; + public TerraImplementationArguments(Vector3Int origin, Rotation rotation, Random random, WritableWorld world, int recursions) { this.rotation = rotation; this.random = random; this.world = world; this.recursions = recursions; - } - - public Buffer getBuffer() { - return buffer; + this.origin = origin; } public int getRecursions() { @@ -58,4 +58,16 @@ public class TerraImplementationArguments implements ImplementationArguments { public WritableWorld getWorld() { return world; } + + public Vector3Int getOrigin() { + return origin; + } + + public void setMark(Vector3 pos, String mark) { + marks.put(pos, mark); + } + + public String getMark(Vector3 pos) { + return marks.get(pos); + } } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/StateFunctionBuilder.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/StateFunctionBuilder.java index 94226aa18..cecd17112 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/StateFunctionBuilder.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/StateFunctionBuilder.java @@ -29,7 +29,7 @@ public class StateFunctionBuilder implements FunctionBuilder { public StateFunction build(List> argumentList, Position position) { if(argumentList.size() < 4) throw new ParseException("Expected data", position); return new StateFunction((Returnable) argumentList.get(0), (Returnable) argumentList.get(1), - (Returnable) argumentList.get(2), (Returnable) argumentList.get(3), platform, position); + (Returnable) argumentList.get(2), (Returnable) argumentList.get(3), position); } @Override diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java index 9b22af3f3..ca2bf5558 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BiomeFunction.java @@ -50,10 +50,9 @@ public class BiomeFunction implements Function { BiomeProvider grid = arguments.getWorld().getBiomeProvider(); - return grid.getBiome(arguments.getBuffer() - .getOrigin() - .clone() - .add(new Vector3(FastMath.roundToInt(xz.getX()), + return grid.getBiome(arguments.getOrigin() + .toVector3() + .add(Vector3.of(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))), arguments.getWorld().getSeed()).getID(); } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java index 8160f9fdb..cb658208c 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.terra.api.block.state.properties.base.Properties; + import net.jafama.FastMath; import java.util.HashMap; @@ -26,8 +28,12 @@ import com.dfsek.terra.api.util.RotationUtil; import com.dfsek.terra.api.util.vector.Vector2; import com.dfsek.terra.api.util.vector.Vector3; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class BlockFunction implements Function { + private static final Logger logger = LoggerFactory.getLogger(BlockFunction.class); protected final Returnable x, y, z; protected final Returnable blockData; protected final Platform platform; @@ -72,10 +78,20 @@ 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), platform, arguments.isWaterlog()), - new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), - FastMath.roundToInt(xz.getZ()))); + try { + Vector3 set = Vector3.of(FastMath.roundToInt(xz.getX()), + y.apply(implementationArguments, variableMap).doubleValue(), + FastMath.roundToInt(xz.getZ())).add(arguments.getOrigin()); + BlockState current = arguments.getWorld().getBlockState(set); + if(overwrite.apply(implementationArguments, variableMap) || current.isAir()) { + if(arguments.isWaterlog() && current.has(Properties.WATERLOGGED) && current.getBlockType().isWater()) { + current.set(Properties.WATERLOGGED, true); + } + arguments.getWorld().setBlockState(set, rot); + } + } catch(RuntimeException e) { + logger.error("Failed to place block at location {}", arguments.getOrigin(), e); + } } protected BlockState getBlockState(ImplementationArguments arguments, Map> variableMap) { diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java index 488a76446..ef19e5e3b 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/CheckBlockFunction.java @@ -44,12 +44,11 @@ public class CheckBlockFunction implements Function { RotationUtil.rotateVector(xz, arguments.getRotation()); String data = arguments.getWorld() - .getBlockState(arguments.getBuffer() - .getOrigin() - .clone() - .add(new Vector3(FastMath.roundToInt(xz.getX()), - y.apply(implementationArguments, variableMap) - .doubleValue(), FastMath.roundToInt(xz.getZ())))) + .getBlockState(arguments.getOrigin() + .toVector3() + .add(Vector3.of(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; diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/EntityFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/EntityFunction.java index 051167cab..d3f46ed61 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/EntityFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/EntityFunction.java @@ -19,7 +19,9 @@ import com.dfsek.terra.addons.terrascript.parser.lang.variables.Variable; import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments; import com.dfsek.terra.addons.terrascript.tokenizer.Position; import com.dfsek.terra.api.Platform; +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.util.RotationUtil; import com.dfsek.terra.api.util.vector.Vector2; import com.dfsek.terra.api.util.vector.Vector3; @@ -50,9 +52,8 @@ public class EntityFunction implements Function { z.apply(implementationArguments, variableMap).doubleValue()); RotationUtil.rotateVector(xz, arguments.getRotation()); - - arguments.getBuffer().addItem(new BufferedEntity(data, platform), - new Vector3(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ())); + Entity entity = arguments.getWorld().spawnEntity(Vector3.of(xz.getX(), y.apply(implementationArguments, variableMap).doubleValue(), xz.getZ()).add(arguments.getOrigin()).add(0.5, 0, 0.5), data); + platform.getEventManager().callEvent(new EntitySpawnEvent(entity.world().getPack(), entity)); return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java index 4f401700f..d5895fc91 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/GetMarkFunction.java @@ -40,8 +40,8 @@ public class GetMarkFunction implements Function { 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()))); + String mark = arguments.getMark(Vector3.of(FastMath.floorToInt(xz.getX()), FastMath.floorToInt( + y.apply(implementationArguments, variableMap).doubleValue()), FastMath.floorToInt(xz.getZ())).add(arguments.getOrigin())); return mark == null ? "" : mark; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java index 256a99c02..509fa353b 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java @@ -7,13 +7,19 @@ package com.dfsek.terra.addons.terrascript.script.functions; +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.util.vector.Vector3; + import net.jafama.FastMath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; +import java.util.Random; -import com.dfsek.terra.addons.terrascript.buffer.items.BufferedLootApplication; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.functions.Function; @@ -26,7 +32,6 @@ 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.util.vector.Vector2; -import com.dfsek.terra.api.util.vector.Vector3; public class LootFunction implements Function { @@ -59,12 +64,37 @@ public class LootFunction implements Function { RotationUtil.rotateVector(xz, arguments.getRotation()); String id = data.apply(implementationArguments, variableMap); - registry.get(id).ifPresentOrElse(table -> arguments.getBuffer().addItem(new BufferedLootApplication(table, platform, script), - new Vector3(FastMath.roundToInt(xz.getX()), - y.apply(implementationArguments, variableMap) - .intValue(), - FastMath.roundToInt(xz.getZ()))), - () -> LOGGER.error("No such loot table {}", id)); + + + registry.get(id) + .ifPresentOrElse(table -> { + Vector3 apply = Vector3.of(FastMath.roundToInt(xz.getX()), + y.apply(implementationArguments, variableMap) + .intValue(), + FastMath.roundToInt(xz.getZ())).add(arguments.getOrigin()); + + try { + BlockEntity data = arguments.getWorld().getBlockEntity(apply); + if(!(data instanceof Container container)) { + LOGGER.error("Failed to place loot at {}; block {} is not a container", + apply, data); + return; + } + + LootPopulateEvent event = new LootPopulateEvent(container, table, + arguments.getWorld().getPack(), script); + platform.getEventManager().callEvent(event); + if(event.isCancelled()) return; + + event.getTable().fillInventory(container.getInventory(), + new Random(apply.hashCode())); + data.update(false); + } catch(Exception e) { + LOGGER.error("Could not apply loot at {}", apply, e); + e.printStackTrace(); + } + }, + () -> LOGGER.error("No such loot table {}", id)); return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java index b97524513..fda211de3 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/PullFunction.java @@ -52,9 +52,16 @@ public class PullFunction implements Function { 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()))); + + Vector3 mutable = Vector3.of(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), + FastMath.roundToInt(xz.getZ())).add(arguments.getOrigin()); + while(mutable.getY() > arguments.getWorld().getMinHeight()) { + if(!arguments.getWorld().getBlockState(mutable).isAir()) { + arguments.getWorld().setBlockState(mutable, rot); + break; + } + mutable.subtract(0, 1, 0); + } return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java index 1f462798b..0c2f9ee7a 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/SetMarkFunction.java @@ -43,12 +43,10 @@ public class SetMarkFunction implements Function { 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()))); + arguments.setMark(Vector3.of(FastMath.floorToInt(xz.getX()), + FastMath.floorToInt( + y.apply(implementationArguments, variableMap).doubleValue()), + FastMath.floorToInt(xz.getZ())).add(arguments.getOrigin()), mark.apply(implementationArguments, variableMap)); return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java index e37336138..7070d07bc 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StateFunction.java @@ -7,6 +7,8 @@ package com.dfsek.terra.addons.terrascript.script.functions; +import com.dfsek.terra.api.block.entity.BlockEntity; + import net.jafama.FastMath; import java.util.Map; @@ -23,17 +25,19 @@ import com.dfsek.terra.api.util.RotationUtil; import com.dfsek.terra.api.util.vector.Vector2; import com.dfsek.terra.api.util.vector.Vector3; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class StateFunction implements Function { + private static final Logger LOGGER = LoggerFactory.getLogger(StateFunction.class); private final Returnable data; private final Returnable x, y, z; private final Position position; - private final Platform platform; - public StateFunction(Returnable x, Returnable y, Returnable z, Returnable data, Platform platform, + public StateFunction(Returnable x, Returnable y, Returnable z, Returnable data, Position position) { this.position = position; - this.platform = platform; this.data = data; this.x = x; this.y = y; @@ -47,9 +51,16 @@ public class StateFunction implements Function { z.apply(implementationArguments, variableMap).doubleValue()); RotationUtil.rotateVector(xz, arguments.getRotation()); - arguments.getBuffer().addItem(new BufferedStateManipulator(data.apply(implementationArguments, variableMap)), - new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), - FastMath.roundToInt(xz.getZ()))); + Vector3 origin = new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), + FastMath.roundToInt(xz.getZ())).add(arguments.getOrigin()); + try { + BlockEntity state = arguments.getWorld().getBlockEntity(origin); + state.applyState(data.apply(implementationArguments, variableMap)); + state.update(false); + } catch(Exception e) { + LOGGER.warn("Could not apply BlockState at {}", origin, e); + e.printStackTrace(); + } return null; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java index 4421849b5..13764557a 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java @@ -82,7 +82,7 @@ public class StructureFunction implements Function { } if(script instanceof StructureScript structureScript) { - return structureScript.generate(arguments.getBuffer().getOrigin(), + return structureScript.generate(arguments.getOrigin(), arguments.getWorld() .buffer(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), @@ -90,7 +90,7 @@ public class StructureFunction implements Function { arguments.getRandom(), arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1); } - return script.generate(arguments.getBuffer().getOrigin(), + return script.generate(arguments.getOrigin(), arguments.getWorld() .buffer(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), diff --git a/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java b/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java index 214bfc002..1665e435e 100644 --- a/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java +++ b/common/addons/terrascript-function-check-noise-3d/src/main/java/com/dfsek/terra/addon/terrascript/check/CheckFunction.java @@ -50,7 +50,7 @@ public class CheckFunction implements Function { RotationUtil.rotateVector(xz, arguments.getRotation()); - Vector3 location = arguments.getBuffer().getOrigin().clone().add( + Vector3 location = arguments.getOrigin().toVector3().clone().add( new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).doubleValue(), FastMath.roundToInt(xz.getZ()))); diff --git a/common/api/core/src/main/java/com/dfsek/terra/api/structure/Structure.java b/common/api/core/src/main/java/com/dfsek/terra/api/structure/Structure.java index b0aec87fe..7afd0595b 100644 --- a/common/api/core/src/main/java/com/dfsek/terra/api/structure/Structure.java +++ b/common/api/core/src/main/java/com/dfsek/terra/api/structure/Structure.java @@ -9,14 +9,12 @@ package com.dfsek.terra.api.structure; import java.util.Random; -import com.dfsek.terra.api.structure.buffer.Buffer; import com.dfsek.terra.api.util.Rotation; import com.dfsek.terra.api.util.StringIdentifiable; -import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; import com.dfsek.terra.api.world.WritableWorld; -import com.dfsek.terra.api.world.chunk.Chunk; public interface Structure extends StringIdentifiable { - boolean generate(Vector3 location, WritableWorld world, Random random, Rotation rotation); + boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation); } diff --git a/common/api/core/src/main/java/com/dfsek/terra/api/world/WritableWorld.java b/common/api/core/src/main/java/com/dfsek/terra/api/world/WritableWorld.java index 676270c3f..4f479efe5 100644 --- a/common/api/core/src/main/java/com/dfsek/terra/api/world/WritableWorld.java +++ b/common/api/core/src/main/java/com/dfsek/terra/api/world/WritableWorld.java @@ -4,6 +4,7 @@ import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; public interface WritableWorld extends ReadableWorld { @@ -11,10 +12,18 @@ public interface WritableWorld extends ReadableWorld { setBlockState(position.getBlockX(), position.getBlockY(), position.getBlockZ(), data, physics); } + default void setBlockState(Vector3Int position, BlockState data, boolean physics) { + setBlockState(position.getX(), position.getY(), position.getZ(), data, physics); + } + default void setBlockState(Vector3 position, BlockState data) { setBlockState(position, data, false); } + default void setBlockState(Vector3Int position, BlockState data) { + setBlockState(position, data, false); + } + default void setBlockState(int x, int y, int z, BlockState data) { setBlockState(x, y, z, data, false); } diff --git a/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/Vector3.java b/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/Vector3.java index 7a101b731..69b5e149a 100644 --- a/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/Vector3.java +++ b/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/Vector3.java @@ -7,6 +7,8 @@ package com.dfsek.terra.api.util.vector; +import com.dfsek.terra.api.util.vector.integer.Vector3Int; + import net.jafama.FastMath; import org.jetbrains.annotations.NotNull; @@ -24,6 +26,10 @@ public class Vector3 implements Cloneable { this.z = z; } + public static Vector3 of(double x, double y, double z) { + return new Vector3(x, y, z); + } + public Vector3 multiply(double m) { x *= m; y *= m; @@ -45,6 +51,13 @@ public class Vector3 implements Cloneable { return this; } + public Vector3 add(Vector3Int other) { + this.x += other.getX(); + this.y += other.getY(); + this.z += other.getZ(); + return this; + } + public Vector3 add(Vector2 other) { this.x += other.getX(); this.z += other.getZ(); diff --git a/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/integer/Vector3Int.java b/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/integer/Vector3Int.java index 24ed73225..b1d57a19c 100644 --- a/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/integer/Vector3Int.java +++ b/common/api/util/src/main/java/com/dfsek/terra/api/util/vector/integer/Vector3Int.java @@ -1,5 +1,8 @@ package com.dfsek.terra.api.util.vector.integer; +import com.dfsek.terra.api.util.vector.Vector3; + + public class Vector3Int { private static final Vector3Int ZERO = new Vector3Int(0, 0, 0); private static final Vector3Int UNIT = new Vector3Int(0, 1, 0); @@ -39,7 +42,10 @@ public class Vector3Int { return new Mutable(x, y, z); } - + public Vector3 toVector3() { + return Vector3.of(x, y, z); + } + public static class Mutable { private int x, y, z; @@ -76,5 +82,16 @@ public class Vector3Int { public Vector3Int immutable() { return Vector3Int.of(x, y, z); } + + public Mutable add(int x, int y, int z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + public Vector3 toVector3() { + return Vector3.of(x, y, z); + } } }