diff --git a/common/src/main/java/com/dfsek/terra/api/math/vector/Location.java b/common/src/main/java/com/dfsek/terra/api/math/vector/Location.java index 38e67bc13..ee86b74ef 100644 --- a/common/src/main/java/com/dfsek/terra/api/math/vector/Location.java +++ b/common/src/main/java/com/dfsek/terra/api/math/vector/Location.java @@ -3,9 +3,13 @@ package com.dfsek.terra.api.math.vector; import com.dfsek.terra.api.platform.block.Block; import com.dfsek.terra.api.platform.world.World; +import java.util.Objects; + public class Location implements Cloneable { private World world; private Vector3 vector; + private double pitch; + private double yaw; public Location(World w, double x, double y, double z) { this.world = w; @@ -102,6 +106,57 @@ public class Location implements Cloneable { return this; } + @Override + public boolean equals(Object obj) { + if(!(obj instanceof Location)) { + return false; + } + final Location other = (Location) obj; + + World world = this.world; + World otherWorld = other.world; + if(!Objects.equals(world, otherWorld)) { + return false; + } + if(Double.doubleToLongBits(this.vector.getX()) != Double.doubleToLongBits(other.vector.getX())) { + return false; + } + if(Double.doubleToLongBits(this.vector.getY()) != Double.doubleToLongBits(other.vector.getY())) { + return false; + } + return Double.doubleToLongBits(this.vector.getZ()) == Double.doubleToLongBits(other.vector.getZ()); + } + + public double getPitch() { + return pitch; + } + + public void setPitch(double pitch) { + this.pitch = pitch; + } + + public double getYaw() { + return yaw; + } + + public void setYaw(double yaw) { + this.yaw = yaw; + } + + @Override + public int hashCode() { + int hash = 3; + + World world = (this.world == null) ? null : this.world; + hash = 19 * hash + (world != null ? world.hashCode() : 0); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.vector.getX()) ^ (Double.doubleToLongBits(this.vector.getX()) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.vector.getY()) ^ (Double.doubleToLongBits(this.vector.getY()) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.vector.getZ()) ^ (Double.doubleToLongBits(this.vector.getZ()) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.pitch) ^ Double.doubleToLongBits(this.pitch) >>> 32); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.yaw) ^ Double.doubleToLongBits(this.yaw) >>> 32); + return hash; + } + public Vector3 toVector() { return vector.clone(); } 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 acf7b147d..8449d66e7 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 @@ -22,11 +22,19 @@ import org.apache.commons.io.IOUtils; import java.io.IOException; import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Random; public class StructureScript { private final Block block; private final String id; + private final LinkedHashMap cache = new LinkedHashMap() { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return this.size() > 128; + } + }; public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry) { Parser parser; @@ -67,10 +75,15 @@ public class StructureScript { } public boolean execute(Location location, Chunk chunk, Random random, Rotation rotation) { - StructureBuffer buffer = new StructureBuffer(location); - Block.ReturnLevel level = block.apply(buffer, rotation, random, 0); + StructureBuffer buffer = cache.computeIfAbsent(location, loc -> { + System.out.println("Recalculating for (" + loc.getBlockX() + ", " + loc.getBlockZ() + "), chunk {" + chunk.getX() + ", " + chunk.getZ() + "}, cache size: " + cache.size()); + StructureBuffer buf = new StructureBuffer(loc); + Block.ReturnLevel level = block.apply(buf, rotation, random, 0); + buf.setSucceeded(!level.equals(Block.ReturnLevel.FAIL)); + return buf; + }); buffer.paste(chunk); - return !level.equals(Block.ReturnLevel.FAIL); + return buffer.succeeded(); } public void executeInBuffer(Buffer buffer, Random random, Rotation rotation, int recursions) { diff --git a/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/StructureBuffer.java b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/StructureBuffer.java index 3d6ef9494..bb0afb6dd 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/StructureBuffer.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/structure/buffer/StructureBuffer.java @@ -13,6 +13,7 @@ import java.util.Map; public class StructureBuffer implements Buffer { private final Map bufferedItemMap = new HashMap<>(); private final Location origin; + private boolean succeeded; public StructureBuffer(Location origin) { this.origin = origin; @@ -54,6 +55,13 @@ public class StructureBuffer implements Buffer { return this; } + public void setSucceeded(boolean succeeded) { + this.succeeded = succeeded; + } + + public boolean succeeded() { + return succeeded; + } @Override public Location getOrigin() {