From ebeaad0b4e66245c0907350ace500badc412b6e9 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 06:27:38 -0400 Subject: [PATCH 01/39] Worm iterators --- .../volmit/iris/util/noise/WormIterator2.java | 6 +- .../volmit/iris/util/noise/WormIterator3.java | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/volmit/iris/util/noise/WormIterator3.java diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java index 9c229472c..ccef8d12a 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java @@ -45,7 +45,11 @@ public class WormIterator2 { { worm = new Worm2(x, z, 0, 0); } - + + worm.getX().setVelocity(p.noise(worm.getX().getPosition(), 0)); + worm.getZ().setVelocity(p.noise(worm.getZ().getPosition(), 0)); + worm.step(); + return worm; } } diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java new file mode 100644 index 000000000..b49396d5b --- /dev/null +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java @@ -0,0 +1,60 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.noise; + +import com.volmit.iris.util.function.NoiseProvider; +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class WormIterator3 { + private transient Worm3 worm; + private int x; + private int y; + private int z; + private int maxDistance; + private int maxIterations; + + public boolean hasNext() + { + double dist = maxDistance - (Math.max(Math.max(Math.abs(worm.getX().getVelocity()), + Math.abs(worm.getZ().getVelocity())), + Math.abs(worm.getY().getVelocity())) + 1); + return maxIterations > 0 && + ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) + + ((y * y) - (worm.getY().getPosition() * worm.getY().getPosition())) + + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; + } + + public Worm3 next(NoiseProvider p) + { + if(worm == null) + { + worm = new Worm3(x, y, z, 0, 0, 0); + } + + worm.getX().setVelocity(p.noise(worm.getX().getPosition(), 0)); + worm.getY().setVelocity(p.noise(worm.getY().getPosition(), 0)); + worm.getZ().setVelocity(p.noise(worm.getZ().getPosition(), 0)); + worm.step(); + + return worm; + } +} From de5ce2660db3bf9c930fc63551c39900c73e454a Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 19 Aug 2021 07:06:10 -0400 Subject: [PATCH 02/39] Create gradlebuild.yml --- .github/workflows/gradlebuild.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/gradlebuild.yml diff --git a/.github/workflows/gradlebuild.yml b/.github/workflows/gradlebuild.yml new file mode 100644 index 000000000..8c011a251 --- /dev/null +++ b/.github/workflows/gradlebuild.yml @@ -0,0 +1,25 @@ +name: Android CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: set up JDK 16 + uses: actions/setup-java@v2 + with: + java-version: '16' + distribution: 'adopt' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build From e7727afbe899dacbef98bd6173a654c894ca0ad1 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 19 Aug 2021 07:06:35 -0400 Subject: [PATCH 03/39] Update gradlebuild.yml --- .github/workflows/gradlebuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradlebuild.yml b/.github/workflows/gradlebuild.yml index 8c011a251..c2e7040dc 100644 --- a/.github/workflows/gradlebuild.yml +++ b/.github/workflows/gradlebuild.yml @@ -1,4 +1,4 @@ -name: Android CI +name: Gradle Build on: push: From fc73e0e482621c887977075341a3aecc70044b3f Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 16:36:45 -0400 Subject: [PATCH 04/39] Advanced mantle editing --- .../com/volmit/iris/util/mantle/Mantle.java | 513 +++++++++++++++++- .../java/com/volmit/iris/util/math/INode.java | 47 ++ .../math/KochanekBartelsInterpolation.java | 248 +++++++++ .../iris/util/math/PathInterpolation.java | 70 +++ 4 files changed, 865 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/math/INode.java create mode 100644 src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java create mode 100644 src/main/java/com/volmit/iris/util/math/PathInterpolation.java diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index e17ae0b32..8113ef80b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -18,8 +18,10 @@ package com.volmit.iris.util.mantle; +import com.google.common.collect.ImmutableList; import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.documentation.BlockCoordinates; @@ -28,17 +30,20 @@ import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer4; +import com.volmit.iris.util.math.INode; +import com.volmit.iris.util.math.KochanekBartelsInterpolation; import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.PathInterpolation; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.HyperLock; import com.volmit.iris.util.parallel.MultiBurst; +import org.bukkit.util.Vector; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Map; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; @@ -79,6 +84,13 @@ public class Mantle { Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } + /** + * Raise a flag if it is lowered currently, If the flag was raised, execute the runnable + * @param x the chunk x + * @param z the chunk z + * @param flag the flag to raise + * @param r the runnable to fire if the flag is now raised (and was previously lowered) + */ @ChunkCoordinates public void raiseFlag(int x, int z, MantleFlag flag, Runnable r) { if (!hasFlag(x, z, flag)) { @@ -87,6 +99,13 @@ public class Mantle { } } + /** + * Lower a flag if it is raised. If the flag was lowered (meaning it was previously raised), execute the runnable + * @param x the chunk x + * @param z the chunk z + * @param flag the flag to lower + * @param r the runnable that is fired if the flag was raised but is now lowered + */ @ChunkCoordinates public void lowerFlag(int x, int z, MantleFlag flag, Runnable r) { if (hasFlag(x, z, flag)) { @@ -95,11 +114,27 @@ public class Mantle { } } + /** + * Flag or unflag a chunk + * @param x the chunk x + * @param z the chunk z + * @param flag the flag + * @param flagged should it be set to flagged or not + */ @ChunkCoordinates public void flag(int x, int z, MantleFlag flag, boolean flagged) { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + /** + * Iterate data in a chunk + * @param x the chunk x + * @param z the chunk z + * @param type the type of data to iterate + * @param iterator the iterator (x,y,z,data) -> do stuff + * @param requiredFlags any required flags that must be met for this chunk to be iterated + * @param the type of data to iterate + */ @ChunkCoordinates public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { for (MantleFlag i : requiredFlags) { @@ -111,17 +146,13 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator); } - @ChunkCoordinates - public void iterateChunk(int x, int z, Class type, Consumer4 iterator, BurstExecutor e, MantleFlag... requiredFlags) { - for (MantleFlag i : requiredFlags) { - if (!hasFlag(x, z, i)) { - return; - } - } - - get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e); - } - + /** + * Does this chunk have a flag on it? + * @param x the x + * @param z the z + * @param flag the flag to test + * @return true if it's flagged + */ @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); @@ -190,6 +221,10 @@ public class Mantle { .get(x & 15, y & 15, z & 15); } + /** + * Is this mantle closed + * @return true if it is + */ public boolean isClosed() { return closed.get(); @@ -367,10 +402,23 @@ public class Mantle { })); } + /** + * Get the file for a region + * @param folder the folder + * @param x the x coord + * @param z the z coord + * @return the file + */ public static File fileForRegion(File folder, int x, int z) { return fileForRegion(folder, key(x, z)); } + /** + * Get the file for the given region + * @param folder the data folder + * @param key the region key + * @return the file + */ public static File fileForRegion(File folder, Long key) { String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString(); File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp"); @@ -378,6 +426,12 @@ public class Mantle { return f; } + /** + * Get the long value representing a chunk or region coordinate + * @param x the x + * @param z the z + * @return the value + */ public static Long key(int x, int z) { return Cache.key(x, z); } @@ -385,4 +439,437 @@ public class Mantle { public void saveAll() { } + + /** + * Set a sphere into the mantle + * @param cx the center x + * @param cy the center y + * @param cz the center z + * @param radius the radius of this sphere + * @param fill should it be filled? or just the outer shell? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setSphere(int cx, int cy, int cz, double radius, boolean fill, T data) + { + setElipsoid(cx, cy, cz, radius, radius, radius, fill, data); + } + + /** + * Set an elipsoid into the mantle + * @param cx the center x + * @param cy the center y + * @param cz the center z + * @param rx the x radius + * @param ry the y radius + * @param rz the z radius + * @param fill should it be filled or just the outer shell? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setElipsoid(int cx, int cy, int cz, double rx, double ry, double rz, boolean fill, T data) + { + rx += 0.5; + ry += 0.5; + rz += 0.5; + final double invRadiusX = 1 / rx; + final double invRadiusY = 1 / ry; + final double invRadiusZ = 1 / rz; + final int ceilRadiusX = (int) Math.ceil(rx); + final int ceilRadiusY = (int) Math.ceil(ry); + final int ceilRadiusZ = (int) Math.ceil(rz); + double nextXn = 0; + + forX: for (int x = 0; x <= ceilRadiusX; ++x) { + final double xn = nextXn; + nextXn = (x + 1) * invRadiusX; + double nextYn = 0; + forY: for (int y = 0; y <= ceilRadiusY; ++y) { + final double yn = nextYn; + nextYn = (y + 1) * invRadiusY; + double nextZn = 0; + for (int z = 0; z <= ceilRadiusZ; ++z) { + final double zn = nextZn; + nextZn = (z + 1) * invRadiusZ; + + double distanceSq = lengthSq(xn, yn, zn); + if (distanceSq > 1) { + if (z == 0) { + if (y == 0) { + break forX; + } + break forY; + } + break; + } + + if (!fill) { + if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1) { + continue; + } + } + + set(x + cx,y + cy,z + cz, data); + set(-x + cx,y + cy,z + cz, data); + set(x + cx,-y + cy,z + cz, data); + set(x + cx,y + cy,-z + cz, data); + set(-x + cx,y + cy,-z + cz, data); + set(-x + cx,-y + cy,z + cz, data); + set(x + cx,-y + cy,-z + cz, data); + set(-x + cx,y + cy,-z + cz, data); + set(-x + cx,-y + cy,-z + cz, data); + } + } + } + } + + /** + * Set a cuboid of data in the mantle + * @param x1 the min x + * @param y1 the min y + * @param z1 the min z + * @param x2 the max x + * @param y2 the max y + * @param z2 the max z + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setCuboid(int x1, int y1, int z1, int x2, int y2, int z2, T data) + { + int j,k; + + for(int i = x1; i <= x2; i++) + { + for(j = x1; j <= x2; j++) + { + for(k = x1; k <= x2; k++) + { + set(i,j,k,data); + } + } + } + } + + /** + * Set a pyramid of data in the mantle + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param size the size of the pyramid (width of base & height) + * @param filled should it be filled or hollow + * @param the type of data to apply to the mantle + */ + @SuppressWarnings("ConstantConditions") + public void setPyramid(int cx, int cy, int cz, T data, int size, boolean filled) { + int height = size; + + for (int y = 0; y <= height; ++y) { + size--; + for (int x = 0; x <= size; ++x) { + for (int z = 0; z <= size; ++z) { + if ((filled && z <= size && x <= size) || z == size || x == size) { + set(x + cx, y + cy, z + cz, data); + set(-x + cx, y + cy, z + cz, data); + set(x + cx, y + cy, -z + cz, data); + set(-x + cx, y + cy, -z + cz, data); + } + } + } + } + } + + /** + * Set a 3d tube spline interpolated with Kochanek Bartels + * @param nodevectors the vector points + * @param radius the radius + * @param filled if it should be filled or hollow + * @param data the data to set + */ + public void setSpline(List nodevectors, double radius, boolean filled, T data) { + setSpline(nodevectors, 0, 0, 0, 10, radius, filled, data); + } + + /** + * Set a 3d tube spline interpolated with Kochanek Bartels + * @param nodevectors the spline points + * @param tension the tension 0 + * @param bias the bias 0 + * @param continuity the continuity 0 + * @param quality the quality 10 + * @param radius the radius + * @param filled filled or hollow + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setSpline(List nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) { + Set vset = new KSet<>(); + List nodes = new ArrayList<>(nodevectors.size()); + PathInterpolation interpol = new KochanekBartelsInterpolation(); + + for (Vector nodevector : nodevectors) { + INode n = new INode(nodevector); + n.setTension(tension); + n.setBias(bias); + n.setContinuity(continuity); + nodes.add(n); + } + + interpol.setNodes(nodes); + double splinelength = interpol.arcLength(0, 1); + for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { + Vector tipv = interpol.getPosition(loop); + vset.add(new IrisPosition(tipv.toBlockVector())); + } + + vset = getBallooned(vset, radius); + if (!filled) { + vset = getHollowed(vset); + } + + set(vset, data); + } + + /** + * Set a 3d line + * @param a the first point + * @param b the second point + * @param radius the radius + * @param filled hollow or filled? + * @param data the data + * @param the type of data to apply to the mantle + */ + public void setLine(IrisPosition a, IrisPosition b, double radius, boolean filled, T data) + { + setLine(ImmutableList.of(a, b), radius, filled, data); + } + + /** + * Set lines for points + * @param vectors the points + * @param radius the radius + * @param filled hollow or filled? + * @param data the data to set + * @param the type of data to apply to the mantle + */ + public void setLine(List vectors, double radius, boolean filled, T data) { + Set vset = new KSet<>(); + + for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) { + IrisPosition pos1 = vectors.get(i); + IrisPosition pos2 = vectors.get(i + 1); + int x1 = pos1.getX(); + int y1 = pos1.getY(); + int z1 = pos1.getZ(); + int x2 = pos2.getX(); + int y2 = pos2.getY(); + int z2 = pos2.getZ(); + int tipx = x1; + int tipy = y1; + int tipz = z1; + int dx = Math.abs(x2 - x1); + int dy = Math.abs(y2 - y1); + int dz = Math.abs(z2 - z1); + + if (dx + dy + dz == 0) { + vset.add(new IrisPosition(tipx, tipy, tipz)); + continue; + } + + int dMax = Math.max(Math.max(dx, dy), dz); + if (dMax == dx) { + for (int domstep = 0; domstep <= dx; domstep++) { + tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1); + tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dx) * (y2 - y1 > 0 ? 1 : -1)); + tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dx) * (z2 - z1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } else if (dMax == dy) { + for (int domstep = 0; domstep <= dy; domstep++) { + tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1); + tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dy) * (x2 - x1 > 0 ? 1 : -1)); + tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dy) * (z2 - z1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } else /* if (dMax == dz) */ { + for (int domstep = 0; domstep <= dz; domstep++) { + tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1); + tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dz) * (y2 - y1 > 0 ? 1 : -1)); + tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dz) * (x2 - x1 > 0 ? 1 : -1)); + + vset.add(new IrisPosition(tipx, tipy, tipz)); + } + } + } + + vset = getBallooned(vset, radius); + + if (!filled) { + vset = getHollowed(vset); + } + + set(vset, data); + } + + /** + * Set a cylinder in the mantle + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param radius the radius + * @param height the height of the cyl + * @param filled filled or not + */ + public void setCylinder(int cx, int cy, int cz, T data, double radius, int height, boolean filled){ + setCylinder(cx, cy, cz, data, radius, radius, height, filled); + } + + /** + * Set a cylinder in the mantle + * @param cx the center x + * @param cy the base y + * @param cz the center z + * @param data the data to set + * @param radiusX the x radius + * @param radiusZ the z radius + * @param height the height of this cyl + * @param filled filled or hollow? + */ + public void setCylinder(int cx, int cy, int cz, T data, double radiusX, double radiusZ, int height, boolean filled) { + int affected = 0; + radiusX += 0.5; + radiusZ += 0.5; + + if (height == 0) { + return; + } else if (height < 0) { + height = -height; + cy = cy - height; + } + + if (cy < 0) { + cy = 0; + } else if (cy + height - 1 > worldHeight) { + height = worldHeight - cy + 1; + } + + final double invRadiusX = 1 / radiusX; + final double invRadiusZ = 1 / radiusZ; + final int ceilRadiusX = (int) Math.ceil(radiusX); + final int ceilRadiusZ = (int) Math.ceil(radiusZ); + double nextXn = 0; + + forX: for (int x = 0; x <= ceilRadiusX; ++x) { + final double xn = nextXn; + nextXn = (x + 1) * invRadiusX; + double nextZn = 0; + for (int z = 0; z <= ceilRadiusZ; ++z) { + final double zn = nextZn; + nextZn = (z + 1) * invRadiusZ; + double distanceSq = lengthSq(xn, zn); + + if (distanceSq > 1) { + if (z == 0) { + break forX; + } + + break; + } + + if (!filled) { + if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) { + continue; + } + } + + for (int y = 0; y < height; ++y) { + set(cx + x, cy + y, cz + z, data); + set(cx + -x, cy + y, cz + z, data); + set(cx + x, cy + y, cz + -z, data); + set(cx + -x, cy + y, cz + -z, data); + } + } + } + } + + + public void set(IrisPosition pos, T data) + { + set(pos.getX(), pos.getY(), pos.getZ(), data); + } + + public void set(List positions, T data) + { + for(IrisPosition i : positions) + { + set(i, data); + } + } + + public void set(Set positions, T data) + { + for(IrisPosition i : positions) + { + set(i, data); + } + } + + private static Set getBallooned(Set vset, double radius) { + Set returnset = new HashSet<>(); + int ceilrad = (int) Math.ceil(radius); + + for (IrisPosition v : vset) { + int tipx = v.getX(); + int tipy = v.getY(); + int tipz = v.getZ(); + + for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { + for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) { + for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { + if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) { + returnset.add(new IrisPosition(loopx, loopy, loopz)); + } + } + } + } + } + return returnset; + } + + private static Set getHollowed(Set vset) { + Set returnset = new KSet<>(); + for (IrisPosition v : vset) { + double x = v.getX(); + double y = v.getY(); + double z = v.getZ(); + if (!(vset.contains(new IrisPosition(x + 1, y, z)) + && vset.contains(new IrisPosition(x - 1, y, z)) + && vset.contains(new IrisPosition(x, y + 1, z)) + && vset.contains(new IrisPosition(x, y - 1, z)) + && vset.contains(new IrisPosition(x, y, z + 1)) + && vset.contains(new IrisPosition(x, y, z - 1)))) { + returnset.add(v); + } + } + return returnset; + } + + private static double hypot(double... pars) { + double sum = 0; + for (double d : pars) { + sum += Math.pow(d, 2); + } + return Math.sqrt(sum); + } + + private static double lengthSq(double x, double y, double z) { + return (x * x) + (y * y) + (z * z); + } + + private static double lengthSq(double x, double z) { + return (x * x) + (z * z); + } } diff --git a/src/main/java/com/volmit/iris/util/math/INode.java b/src/main/java/com/volmit/iris/util/math/INode.java new file mode 100644 index 000000000..cb831d5b0 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/math/INode.java @@ -0,0 +1,47 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.math; + +import lombok.Data; +import org.bukkit.util.Vector; + +@Data +public class INode { + + private Vector position; + private double tension; + private double bias; + private double continuity; + + public INode() { + this(new Vector(0,0,0)); + } + + public INode(INode other) { + this.position = other.position; + + this.tension = other.tension; + this.bias = other.bias; + this.continuity = other.continuity; + } + + public INode(Vector position) { + this.position = position; + } +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java b/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java new file mode 100644 index 000000000..75a01b205 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/math/KochanekBartelsInterpolation.java @@ -0,0 +1,248 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.math; + +import org.bukkit.util.Vector; + +import java.util.Collections; +import java.util.List; + +public class KochanekBartelsInterpolation implements PathInterpolation { + + private List nodes; + private Vector[] coeffA; + private Vector[] coeffB; + private Vector[] coeffC; + private Vector[] coeffD; + private double scaling; + + public KochanekBartelsInterpolation() { + setNodes(Collections.emptyList()); + } + + @Override + public void setNodes(List nodes) { + this.nodes = nodes; + recalc(); + } + + private void recalc() { + final int nNodes = nodes.size(); + coeffA = new Vector[nNodes]; + coeffB = new Vector[nNodes]; + coeffC = new Vector[nNodes]; + coeffD = new Vector[nNodes]; + + if (nNodes == 0) { + return; + } + + INode nodeB = nodes.get(0); + double tensionB = nodeB.getTension(); + double biasB = nodeB.getBias(); + double continuityB = nodeB.getContinuity(); + for (int i = 0; i < nNodes; ++i) { + final double tensionA = tensionB; + final double biasA = biasB; + final double continuityA = continuityB; + + if (i + 1 < nNodes) { + nodeB = nodes.get(i + 1); + tensionB = nodeB.getTension(); + biasB = nodeB.getBias(); + continuityB = nodeB.getContinuity(); + } + + // Kochanek-Bartels tangent coefficients + final double ta = (1 - tensionA) * (1 + biasA) * (1 + continuityA) / 2; // Factor for lhs of d[i] + final double tb = (1 - tensionA) * (1 - biasA) * (1 - continuityA) / 2; // Factor for rhs of d[i] + final double tc = (1 - tensionB) * (1 + biasB) * (1 - continuityB) / 2; // Factor for lhs of d[i+1] + final double td = (1 - tensionB) * (1 - biasB) * (1 + continuityB) / 2; // Factor for rhs of d[i+1] + + coeffA[i] = linearCombination(i, -ta, ta - tb - tc + 2, tb + tc - td - 2, td); + coeffB[i] = linearCombination(i, 2 * ta, -2 * ta + 2 * tb + tc - 3, -2 * tb - tc + td + 3, -td); + coeffC[i] = linearCombination(i, -ta, ta - tb, tb, 0); + //coeffD[i] = linearCombination(i, 0, 1, 0, 0); + coeffD[i] = retrieve(i); // this is an optimization + } + + scaling = nodes.size() - 1; + } + + /** + * Returns the linear combination of the given coefficients with the nodes adjacent to baseIndex. + * + * @param baseIndex node index + * @param f1 coefficient for baseIndex-1 + * @param f2 coefficient for baseIndex + * @param f3 coefficient for baseIndex+1 + * @param f4 coefficient for baseIndex+2 + * @return linear combination of nodes[n-1..n+2] with f1..4 + */ + private Vector linearCombination(int baseIndex, double f1, double f2, double f3, double f4) { + final Vector r1 = retrieve(baseIndex - 1).multiply(f1); + final Vector r2 = retrieve(baseIndex ).multiply(f2); + final Vector r3 = retrieve(baseIndex + 1).multiply(f3); + final Vector r4 = retrieve(baseIndex + 2).multiply(f4); + + return r1.add(r2).add(r3).add(r4); + } + + /** + * Retrieves a node. Indexes are clamped to the valid range. + * + * @param index node index to retrieve + * @return nodes[clamp(0, nodes.length-1)] + */ + private Vector retrieve(int index) { + if (index < 0) { + return fastRetrieve(0); + } + + if (index >= nodes.size()) { + return fastRetrieve(nodes.size() - 1); + } + + return fastRetrieve(index); + } + + private Vector fastRetrieve(int index) { + return nodes.get(index).getPosition(); + } + + @Override + public Vector getPosition(double position) { + if (coeffA == null) { + throw new IllegalStateException("Must call setNodes first."); + } + + if (position > 1) { + return null; + } + + position *= scaling; + + final int index = (int) Math.floor(position); + final double remainder = position - index; + + final Vector a = coeffA[index]; + final Vector b = coeffB[index]; + final Vector c = coeffC[index]; + final Vector d = coeffD[index]; + + return a.multiply(remainder).add(b).multiply(remainder).add(c).multiply(remainder).add(d); + } + + @Override + public Vector get1stDerivative(double position) { + if (coeffA == null) { + throw new IllegalStateException("Must call setNodes first."); + } + + if (position > 1) { + return null; + } + + position *= scaling; + + final int index = (int) Math.floor(position); + //final double remainder = position - index; + + final Vector a = coeffA[index]; + final Vector b = coeffB[index]; + final Vector c = coeffC[index]; + + return a.multiply(1.5 * position - 3.0 * index).add(b).multiply(2.0 * position).add(a.multiply(1.5 * index).subtract(b).multiply(2.0 * index)).add(c).multiply(scaling); + } + + @Override + public double arcLength(double positionA, double positionB) { + if (coeffA == null) { + throw new IllegalStateException("Must call setNodes first."); + } + + if (positionA > positionB) { + return arcLength(positionB, positionA); + } + + positionA *= scaling; + positionB *= scaling; + + final int indexA = (int) Math.floor(positionA); + final double remainderA = positionA - indexA; + + final int indexB = (int) Math.floor(positionB); + final double remainderB = positionB - indexB; + + return arcLengthRecursive(indexA, remainderA, indexB, remainderB); + } + + /** + * Assumes a < b. + */ + private double arcLengthRecursive(int indexLeft, double remainderLeft, int indexRight, double remainderRight) { + switch (indexRight - indexLeft) { + case 0: + return arcLengthRecursive(indexLeft, remainderLeft, remainderRight); + + case 1: + // This case is merely a speed-up for a very common case + return arcLengthRecursive(indexLeft, remainderLeft, 1.0) + + arcLengthRecursive(indexRight, 0.0, remainderRight); + + default: + return arcLengthRecursive(indexLeft, remainderLeft, indexRight - 1, 1.0) + + arcLengthRecursive(indexRight, 0.0, remainderRight); + } + } + + private double arcLengthRecursive(int index, double remainderLeft, double remainderRight) { + final Vector a = coeffA[index].multiply(3.0); + final Vector b = coeffB[index].multiply(2.0); + final Vector c = coeffC[index]; + + final int nPoints = 8; + + double accum = a.multiply(remainderLeft).add(b).multiply(remainderLeft).add(c).length() / 2.0; + for (int i = 1; i < nPoints - 1; ++i) { + double t = ((double) i) / nPoints; + t = (remainderRight - remainderLeft) * t + remainderLeft; + accum += a.multiply(t).add(b).multiply(t).add(c).length(); + } + + accum += a.multiply(remainderRight).add(b).multiply(remainderRight).add(c).length() / 2.0; + return accum * (remainderRight - remainderLeft) / nPoints; + } + + @Override + public int getSegment(double position) { + if (coeffA == null) { + throw new IllegalStateException("Must call setNodes first."); + } + + if (position > 1) { + return Integer.MAX_VALUE; + } + + position *= scaling; + + return (int) Math.floor(position); + } + +} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/math/PathInterpolation.java b/src/main/java/com/volmit/iris/util/math/PathInterpolation.java new file mode 100644 index 000000000..b352230bf --- /dev/null +++ b/src/main/java/com/volmit/iris/util/math/PathInterpolation.java @@ -0,0 +1,70 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.math; + +import org.bukkit.util.Vector; + +import java.util.List; + +public interface PathInterpolation { + + /** + * Sets nodes to be used by subsequent calls to + * {@link #getPosition(double)} and the other methods. + * + * @param nodes the nodes + */ + void setNodes(List nodes); + + /** + * Gets the result of f(position). + * + * @param position the position to interpolate + * @return the result + */ + Vector getPosition(double position); + + /** + * Gets the result of f'(position). + * + * @param position the position to interpolate + * @return the result + */ + Vector get1stDerivative(double position); + + /** + * Gets the result of ∫ab|f'(t)| dt.
+ * That means it calculates the arc length (in meters) between positionA + * and positionB. + * + * @param positionA lower limit + * @param positionB upper limit + * @return the arc length + */ + double arcLength(double positionA, double positionB); + + /** + * Get the segment position. + * + * @param position the position + * @return the segment position + */ + int getSegment(double position); + +} \ No newline at end of file From a1c3bc26c9c672347ee35a8c458bd0848892900a Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 16:36:54 -0400 Subject: [PATCH 05/39] Worms --- .../engine/object/basic/IrisPosition.java | 4 +++ .../engine/object/cave/IrisWormGenerator.java | 36 +++++++++++++++++++ .../volmit/iris/util/noise/WormIterator2.java | 7 ++-- .../volmit/iris/util/noise/WormIterator3.java | 9 ++--- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java index fea93553f..e85f499b1 100644 --- a/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java +++ b/src/main/java/com/volmit/iris/engine/object/basic/IrisPosition.java @@ -54,6 +54,10 @@ public class IrisPosition { public IrisPosition(Vector v) { this(v.getBlockX(), v.getBlockY(), v.getBlockZ()); } + public IrisPosition(double x, double y, double z) { + this((int)x,(int)y,(int)z); + } + public IrisPosition add(IrisPosition relativePosition) { return new IrisPosition(relativePosition.x + x, relativePosition.y + y, relativePosition.z + z); diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java index 1717af527..c8f036dc4 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java @@ -18,6 +18,8 @@ package com.volmit.iris.engine.object.cave; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.Required; @@ -27,7 +29,11 @@ import com.volmit.iris.engine.object.noise.IrisGeneratorStyle; import com.volmit.iris.engine.object.noise.IrisNoiseGenerator; import com.volmit.iris.engine.object.noise.IrisStyledRange; import com.volmit.iris.engine.object.noise.NoiseStyle; +import com.volmit.iris.util.function.NoiseProvider; +import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.Worm; +import com.volmit.iris.util.noise.WormIterator2; +import com.volmit.iris.util.noise.WormIterator3; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -56,4 +62,34 @@ public class IrisWormGenerator implements IRare { @Desc("The thickness of the worm over distance") private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(7) .setStyle(new IrisGeneratorStyle(NoiseStyle.SIMPLEX)); + + private transient final AtomicCache angleProviderCache = new AtomicCache<>(); + + public void test() + { + + } + + public NoiseProvider getAngleProvider(RNG rng, IrisData data) + { + return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).noise(xx, zz)); + } + + public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z) + { + return WormIterator2.builder() + .maxDistance(maxDistance) + .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) + .noise(getAngleProvider(rng, data)).x(x).z(z) + .build(); + } + + public WormIterator3 iterate3D(RNG rng, IrisData data, int x, int y, int z) + { + return WormIterator3.builder() + .maxDistance(maxDistance) + .maxIterations(maxSegments == -1 ? maxDistance : maxSegments) + .noise(getAngleProvider(rng, data)).x(x).z(z).y(y) + .build(); + } } diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java index ccef8d12a..cd34fd776 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java @@ -26,6 +26,7 @@ import lombok.Data; @Data public class WormIterator2 { private transient Worm2 worm; + private transient NoiseProvider noise; private int x; private int z; private int maxDistance; @@ -39,15 +40,15 @@ public class WormIterator2 { + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; } - public Worm2 next(NoiseProvider p) + public Worm2 next() { if(worm == null) { worm = new Worm2(x, z, 0, 0); } - worm.getX().setVelocity(p.noise(worm.getX().getPosition(), 0)); - worm.getZ().setVelocity(p.noise(worm.getZ().getPosition(), 0)); + worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); + worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0)); worm.step(); return worm; diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java index b49396d5b..9ef523c0e 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java @@ -29,6 +29,7 @@ public class WormIterator3 { private int x; private int y; private int z; + private transient NoiseProvider noise; private int maxDistance; private int maxIterations; @@ -43,16 +44,16 @@ public class WormIterator3 { + ((z * z) - (worm.getZ().getPosition() * worm.getZ().getPosition())) < dist * dist; } - public Worm3 next(NoiseProvider p) + public Worm3 next() { if(worm == null) { worm = new Worm3(x, y, z, 0, 0, 0); } - worm.getX().setVelocity(p.noise(worm.getX().getPosition(), 0)); - worm.getY().setVelocity(p.noise(worm.getY().getPosition(), 0)); - worm.getZ().setVelocity(p.noise(worm.getZ().getPosition(), 0)); + worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); + worm.getY().setVelocity(noise.noise(worm.getY().getPosition(), 0)); + worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0)); worm.step(); return worm; From bbf660d80ecf8ee8d4c0861d9f1958005535cbb3 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 22:26:31 -0400 Subject: [PATCH 06/39] Caves --- .../iris/core/project/loader/IrisData.java | 7 ++ .../iris/engine/object/cave/IrisCave.java | 64 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index 5b18e1fdc..dbb52eb4d 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; +import com.volmit.iris.engine.object.cave.IrisCave; import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.entity.IrisEntity; @@ -63,6 +64,7 @@ public class IrisData { private ResourceLoader expressionLoader; private ResourceLoader objectLoader; private ResourceLoader scriptLoader; + private ResourceLoader caveLoader; private KMap, ResourceLoader> loaders = new KMap<>(); private boolean closed; private final File dataFolder; @@ -199,6 +201,7 @@ public class IrisData { this.jigsawStructureLoader = registerLoader(IrisJigsawStructure.class); this.jigsawPieceLoader = registerLoader(IrisJigsawPiece.class); this.generatorLoader = registerLoader(IrisGenerator.class); + this.caveLoader = registerLoader(IrisCave.class); this.blockLoader = registerLoader(IrisBlockData.class); this.expressionLoader = registerLoader(IrisExpression.class); this.objectLoader = registerLoader(IrisObject.class); @@ -273,6 +276,10 @@ public class IrisData { return loadAny(key, (dm) -> dm.getRegionLoader().load(key, false)); } + public static IrisCave loadAnyCave(String key) { + return loadAny(key, (dm) -> dm.getCaveLoader().load(key, false)); + } + public static IrisDimension loadAnyDimension(String key) { return loadAny(key, (dm) -> dm.getDimensionLoader().load(key, false)); } diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java new file mode 100644 index 000000000..db1eede0f --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java @@ -0,0 +1,64 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.cave; + +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.noise.IrisWorm; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.Worm; +import com.volmit.iris.util.noise.Worm3; +import com.volmit.iris.util.noise.WormIterator3; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Translate objects") +@Data +public class IrisCave extends IrisRegistrant { + @Desc("Define the shape of this cave") + private IrisWorm worm; + + @Override + public String getFolderName() { + return "caves"; + } + + @Override + public String getTypeName() { + return "Cave"; + } + + public void generateCave(RNG rng, IrisData data, int x, int y, int z) + { + WormIterator3 w = worm.iterate3D(rng, data, x, y, z); + + while(w.hasNext()) + { + Worm3 wx = w.next(); + } + } +} From bbf441c3b4d9c8d661c0c6b8c8f1f4d5bb1c11b8 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 22:26:40 -0400 Subject: [PATCH 07/39] Worms --- build.gradle | 2 +- .../engine/modifier/IrisCaveModifier2.java | 75 ------------------- .../IrisWorm.java} | 23 +++--- 3 files changed, 12 insertions(+), 88 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java rename src/main/java/com/volmit/iris/engine/object/{cave/IrisWormGenerator.java => noise/IrisWorm.java} (84%) diff --git a/build.gradle b/build.gradle index fc5a8fed1..b32a90615 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.4' +version '1.7.5' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris' diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java deleted file mode 100644 index bb496eaae..000000000 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier2.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.modifier; - -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineAssignedModifier; -import com.volmit.iris.engine.object.common.CaveResult; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.FastNoiseDouble; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import org.bukkit.block.data.BlockData; - -public class IrisCaveModifier2 extends EngineAssignedModifier { - public static final BlockData CAVE_AIR = B.get("CAVE_AIR"); - public static final BlockData AIR = B.get("AIR"); - private static final KList EMPTY = new KList<>(); - private final FastNoiseDouble gg; - private final RNG rng; - - public IrisCaveModifier2(Engine engine) { - super(engine, "Cave"); - rng = new RNG(engine.getWorld().seed() + 28934555); - gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax()); - } - - @Override - public void onModify(int x, int z, Hunk a, boolean multicore) { - if (!getDimension().isCaves()) { - return; - } - - PrecisionStopwatch p = PrecisionStopwatch.start(); - if (multicore) { - BurstExecutor e = getEngine().burst().burst(a.getWidth()); - for (int i = 0; i < a.getWidth(); i++) { - int finalI = i; - e.queue(() -> modifySliver(x, z, finalI, a)); - } - - e.complete(); - } else { - for (int i = 0; i < a.getWidth(); i++) { - modifySliver(x, z, i, a); - } - } - - getEngine().getMetrics().getCave().put(p.getMilliseconds()); - } - - public void modifySliver(int x, int z, int finalI, Hunk a) { - for (int j = 0; j < a.getDepth(); j++) { - - } - } -} diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java similarity index 84% rename from src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java rename to src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java index c8f036dc4..5e0a4f61a 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisWormGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.volmit.iris.engine.object.cave; +package com.volmit.iris.engine.object.noise; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -44,14 +44,14 @@ import lombok.experimental.Accessors; @AllArgsConstructor @Desc("Generate worms") @Data -public class IrisWormGenerator implements IRare { +public class IrisWorm implements IRare { @Required @Desc("Typically a 1 in RARITY on a per chunk basis") @MinNumber(1) private int rarity = 15; @Desc("The style used to determine the curvature of this worm") - private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(); + private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(NoiseStyle.PERLIN); @Desc("The max block distance this worm can travel from its start. This can have performance implications at ranges over 1,000 blocks but it's not too serious, test.") private int maxDistance = 128; @@ -59,20 +59,19 @@ public class IrisWormGenerator implements IRare { @Desc("The max segments, or iterations this worm can execute on. Setting this to -1 will allow it to run up to the maxDistance's value of iterations (default)") private int maxSegments = -1; - @Desc("The thickness of the worm over distance") - private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(7) - .setStyle(new IrisGeneratorStyle(NoiseStyle.SIMPLEX)); + @Desc("The distance between segments") + private IrisStyledRange segmentDistance = new IrisStyledRange().setMin(4).setMax(7) + .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); + + @Desc("The thickness of the worms. Each individual worm has the same thickness while traveling however, each spawned worm will vary in thickness.") + private IrisStyledRange girth = new IrisStyledRange().setMin(3).setMax(5) + .setStyle(new IrisGeneratorStyle(NoiseStyle.PERLIN)); private transient final AtomicCache angleProviderCache = new AtomicCache<>(); - public void test() - { - - } - public NoiseProvider getAngleProvider(RNG rng, IrisData data) { - return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).noise(xx, zz)); + return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).noise(xx, zz) * segmentDistance.get(rng, xx, zz, data)); } public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z) From 3fc907e50fe813b73039244899338856256c0cef Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 22:39:04 -0400 Subject: [PATCH 08/39] Cave placers --- .../iris/engine/object/cave/IrisCave.java | 15 +-- .../engine/object/cave/IrisCavePlacer.java | 99 +++++++++++++++++++ 2 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java index db1eede0f..740933cac 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java @@ -22,6 +22,9 @@ import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.noise.IrisWorm; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.Worm; import com.volmit.iris.util.noise.Worm3; @@ -31,6 +34,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.Vector; @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @@ -51,14 +56,4 @@ public class IrisCave extends IrisRegistrant { public String getTypeName() { return "Cave"; } - - public void generateCave(RNG rng, IrisData data, int x, int y, int z) - { - WormIterator3 w = worm.iterate3D(rng, data, x, y, z); - - while(w.hasNext()) - { - Worm3 wx = w.next(); - } - } } diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java new file mode 100644 index 000000000..a3142e307 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java @@ -0,0 +1,99 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.object.cave; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.RegistryListResource; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.Worm3; +import com.volmit.iris.util.noise.WormIterator3; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.Vector; + +import java.util.concurrent.atomic.AtomicBoolean; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Translate objects") +@Data +public class IrisCavePlacer implements IRare { + private static final BlockData CAVE_AIR = B.get("CAVE_AIR"); + + @Required + @Desc("Typically a 1 in RARITY on a per chunk basis") + @MinNumber(1) + private int rarity = 15; + + @MinNumber(1) + @Required + @RegistryListResource(IrisCave.class) + private String cave; + + private transient final AtomicCache caveCache = new AtomicCache<>(); + private transient final AtomicBoolean fail = new AtomicBoolean(false); + + public IrisCave getRealCave(IrisData data) + { + return caveCache.aquire(() -> data.getCaveLoader().load(getCave())); + } + + public void generateCave(Mantle mantle, RNG rng, IrisData data, int x, int y, int z) + { + if(fail.get()) + { + return; + } + + IrisCave cave = getRealCave(data); + + if(cave == null) + { + Iris.warn("Unable to locate cave for generation!"); + fail.set(true); + return; + } + + WormIterator3 w = cave.getWorm().iterate3D(rng, data, x, y, z); + KList points = new KList<>(); + + while(w.hasNext()) + { + Worm3 wx = w.next(); + points.add(new Vector(wx.getX().getPosition(), wx.getY().getPosition(), wx.getZ().getPosition())); + } + + mantle.setSpline(points, cave.getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR); + + // TODO decorate somehow + } +} From 4a1e511262c4be9f8164ee900ea97ba578ba64d2 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 22:39:36 -0400 Subject: [PATCH 09/39] Fixes --- .../java/com/volmit/iris/engine/object/noise/IrisWorm.java | 7 +------ .../java/com/volmit/iris/util/noise/WormIterator2.java | 1 + .../java/com/volmit/iris/util/noise/WormIterator3.java | 1 + 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java index 5e0a4f61a..4ea19c752 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java @@ -44,12 +44,7 @@ import lombok.experimental.Accessors; @AllArgsConstructor @Desc("Generate worms") @Data -public class IrisWorm implements IRare { - @Required - @Desc("Typically a 1 in RARITY on a per chunk basis") - @MinNumber(1) - private int rarity = 15; - +public class IrisWorm { @Desc("The style used to determine the curvature of this worm") private IrisGeneratorStyle angleStyle = new IrisGeneratorStyle(NoiseStyle.PERLIN); diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java index cd34fd776..69655fde8 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator2.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator2.java @@ -45,6 +45,7 @@ public class WormIterator2 { if(worm == null) { worm = new Worm2(x, z, 0, 0); + return worm; } worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java index 9ef523c0e..6f9204d21 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java @@ -49,6 +49,7 @@ public class WormIterator3 { if(worm == null) { worm = new Worm3(x, y, z, 0, 0, 0); + return worm; } worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); From 154adafbcbf0391ac3d82246b18e5d8d92f0a0d6 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Fri, 20 Aug 2021 01:34:14 -0400 Subject: [PATCH 10/39] Test --- src/main/java/com/volmit/iris/Iris.java | 2 +- .../com/volmit/iris/core/gui/VisionGUI.java | 8 +- .../core/gui/components/IrisRenderer.java | 4 +- .../com/volmit/iris/engine/IrisComplex.java | 44 +-- .../com/volmit/iris/engine/IrisEngine.java | 46 +-- .../volmit/iris/engine/IrisEngineMantle.java | 25 +- .../engine/actuator/IrisDecorantActuator.java | 50 +--- .../volmit/iris/engine/framework/Engine.java | 8 +- .../components/MantleCaveComponent.java | 96 +++++++ .../engine/modifier/IrisCaveModifier.java | 261 ------------------ .../engine/modifier/IrisPostModifier.java | 205 +++----------- .../iris/engine/object/biome/IrisBiome.java | 5 + .../object/dimensional/IrisDimension.java | 16 +- .../engine/object/entity/IrisEntitySpawn.java | 20 +- .../engine/object/regional/IrisRegion.java | 5 + .../volmit/iris/util/mantle/MantleFlag.java | 3 +- 16 files changed, 213 insertions(+), 585 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java delete mode 100644 src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index fd93d97a8..d0c360310 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -498,7 +498,7 @@ public class Iris extends VolmitPlugin implements Listener { } catch (Throwable e) { try { System.out.println(instance.getTag() + string.replaceAll("(<([^>]+)>)", "")); - } catch (Throwable ignored1) { + } catch (Throwable ee) { } } diff --git a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index 4cb5c1d04..d46033ccc 100644 --- a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -192,8 +192,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getComplex().getTrueBiomeStreamNoFeatures().get(x, z).getColor(engine, currentType).getRGB(); case BIOME_LAND -> colorFunction = (x, z) -> engine.getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); case BIOME_SEA -> colorFunction = (x, z) -> engine.getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); + // TODO: CAVE + case REGION, CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } @@ -696,8 +696,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener case BIOME, LAYER_LOAD, DECORATOR_LOAD, OBJECT_LOAD, HEIGHT -> r = complex.getTrueBiomeStreamNoFeatures().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); case BIOME_LAND -> r = complex.getLandBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); case BIOME_SEA -> r = complex.getSeaBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); - case REGION -> r = complex.getRegionStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); - case CAVE_LAND -> r = complex.getCaveBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); + // TODO: CAVE + case REGION, CAVE_LAND -> r = complex.getRegionStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); } notify("Opening " + r.getPath() + " in VSCode"); diff --git a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index 944b4af3a..45a2c9bd5 100644 --- a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -41,8 +41,8 @@ public class IrisRenderer { case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); case BIOME_LAND -> colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); case BIOME_SEA -> colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - case REGION -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); - case CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); + // TODO: CAVE + case REGION,CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 43a11c3d3..2ba489c42 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -24,7 +24,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; @@ -70,7 +69,6 @@ public class IrisComplex implements DataProvider { private ProceduralStream islandDepthStream; private ProceduralStream bridgeStream; private ProceduralStream landBiomeStream; - private ProceduralStream caveBiomeStream; private ProceduralStream seaBiomeStream; private ProceduralStream shoreBiomeStream; private ProceduralStream baseBiomeStream; @@ -105,9 +103,8 @@ public class IrisComplex implements DataProvider { public ProceduralStream getBiomeStream(InferredType type) { switch (type) { case CAVE: - return caveBiomeStream; case LAND: - return landBiomeStream; + return landBiomeStream; // TODO??? case SEA: return seaBiomeStream; case SHORE: @@ -123,10 +120,6 @@ public class IrisComplex implements DataProvider { } public IrisComplex(Engine engine) { - this(engine, false); - } - - public IrisComplex(Engine engine, boolean simple) { int cacheSize = 131072; IrisBiome emptyBiome = new IrisBiome(); UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes()); @@ -173,21 +166,6 @@ public class IrisComplex implements DataProvider { islandHeightStream = regionIdentityStream.style(rng.nextParallelRNG(330466), engine.getDimension().getIslandMode().getHeight(), data); islandDepthStream = engine.getDimension().getIslandMode().getIslandDepth().stream(rng.nextParallelRNG(-39578888), data); regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L)); - caveBiomeStream = regionStream.convert((r) - -> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream() - .zoom(r.getCaveBiomeZoom()) - .selectRarity(r.getCaveBiomes(), (i) -> data.getBiomeLoader().load(i)) - .onNull("") - .convertCached((s) -> { - if (s.isEmpty()) { - return emptyBiome; - } - - return data.getBiomeLoader().load(s) - .setInferredType(InferredType.CAVE); - }) - ).convertAware2D(ProceduralStream::get).cache2D(cacheSize); - inferredStreams.put(InferredType.CAVE, caveBiomeStream); landBiomeStream = regionStream.convert((r) -> engine.getDimension().getLandBiomeStyle().create(rng.nextParallelRNG(InferredType.LAND.ordinal()), getData()).stream() .zoom(r.getLandBiomeZoom()) @@ -196,6 +174,7 @@ public class IrisComplex implements DataProvider { .setInferredType(InferredType.LAND)) ).convertAware2D(ProceduralStream::get) .cache2D(cacheSize); + inferredStreams.put(InferredType.CAVE, landBiomeStream); // TODO: CAVE inferredStreams.put(InferredType.LAND, landBiomeStream); seaBiomeStream = regionStream.convert((r) -> engine.getDimension().getSeaBiomeStyle().create(rng.nextParallelRNG(InferredType.SEA.ordinal()), getData()).stream() @@ -318,10 +297,6 @@ public class IrisComplex implements DataProvider { .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D(cacheSize); terrainCeilingDecoration = trueBiomeStream .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D(cacheSize); - terrainCaveSurfaceDecoration = caveBiomeStream - .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D(cacheSize); - terrainCaveCeilingDecoration = caveBiomeStream - .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D(cacheSize); shoreSurfaceDecoration = trueBiomeStream .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.SHORE_LINE)).cache2D(cacheSize); seaSurfaceDecoration = trueBiomeStream @@ -344,21 +319,6 @@ public class IrisComplex implements DataProvider { } } - if (engine.getDimension().isCaves()) { - KList caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null); - boolean again = true; - - while (again) { - again = false; - for (CaveResult i : caves) { - if (i.getCeiling() > m && i.getFloor() < m) { - m = i.getFloor(); - again = true; - } - } - } - } - return m; }, Interpolated.INT).cache2D(cacheSize); baseBiomeIDStream = trueBiomeStream.convertAware2D((b, x, z) -> { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index cb973fc0c..0bc3fc270 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -64,6 +64,7 @@ import org.bukkit.generator.BlockPopulator; import java.io.File; import java.io.IOException; import java.util.Random; +import java.util.Stack; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -101,7 +102,6 @@ public class IrisEngine extends BlockPopulator implements Engine { private EngineActuator decorantActuator; private EngineActuator biomeActuator; private EngineModifier depositModifier; - private EngineModifier caveModifier; private EngineModifier ravineModifier; private EngineModifier postModifier; private final AtomicCache engineData = new AtomicCache<>(); @@ -151,27 +151,35 @@ public class IrisEngine extends BlockPopulator implements Engine { biomeActuator.close(); depositModifier.close(); ravineModifier.close(); - caveModifier.close(); postModifier.close(); effects.close(); } - private void setupEngine() - { - cacheId = RNG.r.nextInt(); - worldManager = new IrisWorldManager(this); - complex = new IrisComplex(this); - execution = new IrisExecutionEnvironment(this); - terrainNormalActuator = new IrisTerrainNormalActuator(this); - terrainIslandActuator = new IrisTerrainIslandActuator(this); - decorantActuator = new IrisDecorantActuator(this); - biomeActuator = new IrisBiomeActuator(this); - depositModifier = new IrisDepositModifier(this); - ravineModifier = new IrisRavineModifier(this); - caveModifier = new IrisCaveModifier(this); - postModifier = new IrisPostModifier(this); - effects = new IrisEngineEffects(this); - J.a(this::computeBiomeMaxes); + private void setupEngine() { + try { + cacheId = RNG.r.nextInt(); + worldManager = new IrisWorldManager(this); + complex = new IrisComplex(this); + execution = new IrisExecutionEnvironment(this); + terrainNormalActuator = new IrisTerrainNormalActuator(this); + terrainIslandActuator = new IrisTerrainIslandActuator(this); + decorantActuator = new IrisDecorantActuator(this); + biomeActuator = new IrisBiomeActuator(this); + depositModifier = new IrisDepositModifier(this); + ravineModifier = new IrisRavineModifier(this); + postModifier = new IrisPostModifier(this); + effects = new IrisEngineEffects(this); + J.a(this::computeBiomeMaxes); + } catch (Throwable e) + { + Iris.error("FATAL: Engine load failure!"); + e.printStackTrace(); + + if(isStudio()) + { + System.exit(0); + } + } } @Override @@ -332,7 +340,6 @@ public class IrisEngine extends BlockPopulator implements Engine { getBiomeActuator().close(); getDepositModifier().close(); getRavineModifier().close(); - getCaveModifier().close(); getPostModifier().close(); getMantle().close(); getComplex().close(); @@ -412,7 +419,6 @@ public class IrisEngine extends BlockPopulator implements Engine { getMantle().generateMatter(x >> 4, z >> 4, multicore); getTerrainActuator().actuate(x, z, vblocks, multicore); getBiomeActuator().actuate(x, z, vbiomes, multicore); - getCaveModifier().modify(x, z, vblocks, multicore); getRavineModifier().modify(x, z, vblocks, multicore); getPostModifier().modify(x, z, vblocks, multicore); getDecorantActuator().actuate(x, z, blocks, multicore); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index 132056578..d520f886a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -22,10 +22,13 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.MantleComponent; +import com.volmit.iris.engine.mantle.components.MantleCaveComponent; import com.volmit.iris.engine.mantle.components.MantleFeatureComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.cave.IrisCave; +import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; @@ -63,6 +66,7 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); + registerComponent(new MantleCaveComponent(this)); } @Override @@ -131,6 +135,7 @@ public class IrisEngineMantle implements EngineMantle { KMap> scalars = new KMap<>(); int x = xg.get(); int z = zg.get(); + int s = 0; if (getEngine().getDimension().isUseMantle()) { KList r = getAllRegions(); @@ -148,6 +153,11 @@ public class IrisEngineMantle implements EngineMantle { for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) { jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension()); } + + for(IrisCavePlacer j : i.getCaves()) + { + s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); + } } for (IrisRegion i : r) { @@ -162,6 +172,16 @@ public class IrisEngineMantle implements EngineMantle { for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) { jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension()); } + + for(IrisCavePlacer j : i.getCaves()) + { + s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); + } + } + + for(IrisCavePlacer j : getDimension().getCaves()) + { + s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); } for (IrisJigsawStructurePlacement j : getEngine().getDimension().getJigsawStructures()) { @@ -265,6 +285,9 @@ public class IrisEngineMantle implements EngineMantle { x = xg.get(); z = zg.get(); + x = Math.max(s, x); + z = Math.max(s, z); + for (IrisDepositGenerator i : getEngine().getDimension().getDeposits()) { int max = i.getMaxDimension(); x = Math.max(max, x); @@ -290,7 +313,7 @@ public class IrisEngineMantle implements EngineMantle { return 0; } - x = Math.max(z, x); + x = Math.max(x, z); int u = x; int v = computeFeatureRange(); x = Math.max(jig, x); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 744f30048..e86b150fc 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -41,7 +41,6 @@ import java.util.function.Predicate; public class IrisDecorantActuator extends EngineAssignedActuator { private static final Predicate PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA); - private final BiPredicate PREDICATE_CAVELIQUID; private final RNG rng; @Getter private final EngineDecorator surfaceDecorator; @@ -64,22 +63,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); shoreLineDecorator = new IrisShoreLineDecorator(getEngine()); seaFloorDecorator = new IrisSeaFloorDecorator(getEngine()); - - PREDICATE_CAVELIQUID = (b, y) -> { - for (IrisCaveLayer layer : getEngine().getDimension().getCaveLayers()) { - if (!layer.getFluid().hasFluid(getData())) { - continue; - } - - if (layer.getFluid().isInverseHeight() && y >= layer.getFluid().getFluidHeight()) { - if (b.matches(layer.getFluid().getFluid(getData()))) return true; - } else if (!layer.getFluid().isInverseHeight() && y <= layer.getFluid().getFluidHeight()) { - if (b.matches(layer.getFluid().getFluid(getData()))) return true; - } - } - return false; - }; - } @BlockCoordinates @@ -99,7 +82,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { int height; int realX = (int) Math.round(modX(x + finalI)); int realZ; - IrisBiome biome, cave; + IrisBiome biome; for (int j=0; j < output.getDepth(); j++) { boolean solid, liquid; int emptyFor = 0; @@ -108,9 +91,8 @@ public class IrisDecorantActuator extends EngineAssignedActuator { realZ = (int) Math.round(modZ(z + j)); height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); biome = getComplex().getTrueBiomeStream().get(realX, realZ); - cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : null; - if (biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { + if (biome.getDecorators().isEmpty()) { continue; } @@ -133,32 +115,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); - - - if (cave != null && cave.getDecorators().isNotEmpty()) { - for (int k = height; k > 0; k--) { - solid = PREDICATE_SOLID.test(output.get(finalI, k, j)); - liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1); - - if (solid) { - if (emptyFor > 0) { - if (liquid) { - getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); - getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); - } else { - getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); - getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); - } - emptyFor = 0; - liquidFor = 0; - } - lastSolid = k; - } else { - emptyFor++; - if (liquid) liquidFor++; - } - } - } } }); } @@ -169,6 +125,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } private boolean shouldRayDecorate() { - return getEngine().getDimension().isCarving() || getEngine().getDimension().isCaves() || getEngine().getDimension().isRavines(); + return getEngine().getDimension().isCarving() || getEngine().getDimension().isRavines(); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 0a3e8e02b..71d770393 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -92,8 +92,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat EngineActuator getBiomeActuator(); - EngineModifier getCaveModifier(); - EngineModifier getRavineModifier(); EngineModifier getDepositModifier(); @@ -194,7 +192,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @BlockCoordinates default IrisBiome getCaveBiome(int x, int z) { - return getComplex().getCaveBiomeStream().get(x, z); + return getComplex().getLandBiomeStream().get(x, z); // TODO!!!!!!!!!! } @BlockCoordinates @@ -356,13 +354,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } IrisRegion region = getComplex().getRegionStream().get(rx, rz); IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz); - IrisBiome biomeUnder = b.getY() < he ? getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; KList tables = new KList<>(); - double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier(); + double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier(); injectTables(tables, getDimension().getLoot()); injectTables(tables, region.getLoot()); injectTables(tables, biomeSurface.getLoot()); - injectTables(tables, biomeUnder.getLoot()); if (tables.isNotEmpty()) { int target = (int) Math.round(tables.size() * multiplier); diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java new file mode 100644 index 000000000..e72c74b71 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java @@ -0,0 +1,96 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.mantle.components; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.jigsaw.PlannedStructure; +import com.volmit.iris.engine.mantle.EngineMantle; +import com.volmit.iris.engine.mantle.IrisMantleComponent; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.cave.IrisCave; +import com.volmit.iris.engine.object.cave.IrisCavePlacer; +import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; +import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; +import com.volmit.iris.engine.object.regional.IrisRegion; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.RNG; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.function.Consumer; + +public class MantleCaveComponent extends IrisMantleComponent { + private final RNG crng; + public MantleCaveComponent(EngineMantle engineMantle) { + super(engineMantle, MantleFlag.CAVE); + crng = new RNG(getEngineMantle().getEngine().getWorld().seed() - 229333333); + } + + @Override + public void generateLayer(int x, int z, Consumer post) { + RNG rng = new RNG(Cache.key(x, z) + seed()); + int xxx = (x << 4) + rng.i(16); + int zzz = (z << 4) + rng.i(16); + + IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); + + for(IrisCavePlacer i : biome.getCaves()) + { + if(rng.nextInt(i.getRarity()) == 0) + { + place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); + return; + } + } + + IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); + + for(IrisCavePlacer i : region.getCaves()) + { + if(rng.nextInt(i.getRarity()) == 0) + { + place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); + return; + } + } + + for(IrisCavePlacer i : getDimension().getCaves()) + { + if(rng.nextInt(i.getRarity()) == 0) + { + place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); + return; + } + } + } + + private void place(IrisCavePlacer cave, int x, int y, int z) { + cave.generateCave(getMantle(), crng, getData(), x, y, z); + } +} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java deleted file mode 100644 index 13ab2cd30..000000000 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.modifier; - -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineAssignedModifier; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.carve.IrisCaveLayer; -import com.volmit.iris.engine.object.common.CaveResult; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.noise.FastNoiseDouble; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; - -import java.util.function.Function; - -public class IrisCaveModifier extends EngineAssignedModifier { - public static final BlockData CAVE_AIR = B.get("CAVE_AIR"); - public static final BlockData AIR = B.get("AIR"); - private static final KList EMPTY = new KList<>(); - private final FastNoiseDouble gg; - private final RNG rng; - - public IrisCaveModifier(Engine engine) { - super(engine, "Cave"); - rng = new RNG(engine.getWorld().seed() + 28934555); - gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax()); - } - - @Override - public void onModify(int x, int z, Hunk a, boolean multicore) { - if (!getDimension().isCaves()) { - return; - } - - PrecisionStopwatch p = PrecisionStopwatch.start(); - if (multicore) { - BurstExecutor e = getEngine().burst().burst(a.getWidth()); - for (int i = 0; i < a.getWidth(); i++) { - int finalI = i; - e.queue(() -> modifySliver(x, z, finalI, a)); - } - - e.complete(); - } else { - for (int i = 0; i < a.getWidth(); i++) { - modifySliver(x, z, i, a); - } - } - - getEngine().getMetrics().getCave().put(p.getMilliseconds()); - } - - public void modifySliver(int x, int z, int finalI, Hunk a) { - for (int j = 0; j < a.getDepth(); j++) { - KList caves = genCaves(x + finalI, z + j, finalI, j, a); - int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j)); - if (caves != null && caves.isNotEmpty()) { - IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j); - - if (cave == null) { - continue; - } - - for (CaveResult cl : caves) { - if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { - continue; - } - - KList floor = cave.generateLayers(x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex()); - KList ceiling = cave.generateLayers(x + finalI + 656, z + j - 656, rng, - he - cl.getCeiling(), - he - cl.getCeiling(), getData(), getComplex()); - - for (int g = 0; g < floor.size(); g++) { - a.set(finalI, cl.getFloor() - g, j, floor.get(g)); - } - - for (int g = ceiling.size() - 1; g > 0; g--) { - a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g)); - } - } - } - } - } - - public KList genCaves(double wxx, double wzz) { - return genCaves(wxx, wzz, 0, 0, null); - } - - public KList genCaves(double wxx, double wzz, int x, int z, Hunk data) { - if (!getDimension().isCaves()) { - return EMPTY; - } - - KList result = new KList<>(); - gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular); - gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub); - gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural); - - for (int i = 0; i < getDimension().getCaveLayers().size(); i++) { - IrisCaveLayer layer = getDimension().getCaveLayers().get(i); - generateCave(result, wxx, wzz, x, z, data, layer, i); - } - - return result; - } - - public void generateCave(KList result, double wxx, double wzz, int x, int z, Hunk data, IrisCaveLayer layer, int seed) { - double scale = layer.getCaveZoom(); - Function fluid = (height) -> - { - if (!layer.getFluid().hasFluid(getData())) { - return CAVE_AIR; - } - - if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) { - return layer.getFluid().getFluid(getData()); - } else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) { - return layer.getFluid().getFluid(getData()); - } - - return CAVE_AIR; - }; - - int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz)); - double wx = wxx + layer.getHorizontalSlope().get(rng, getData(), wxx, wzz); - double wz = wzz + layer.getHorizontalSlope().get(rng, getData(), -wzz, -wxx); - double baseWidth = (14 * scale); - double distanceCheck = 0.0132 * baseWidth; - double distanceTake = 0.0022 * baseWidth; - double caveHeightNoise = layer.getVerticalSlope().get(rng, getData(), wxx, wzz); - - if (caveHeightNoise > 259 || caveHeightNoise < -1) { - return; - } - - // TODO: WARNING HEIGHT - int ceiling = -256; - int floor = 512; - - for (double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) { - double distance = (gg.GetCellular(((wx + (10000 * seed)) / layer.getCaveZoom()), ((wz - (10000 * seed)) / layer.getCaveZoom())) + 1D) / 2D; - if (distance < distanceCheck - (tunnelHeight * distanceTake)) { - int caveHeight = (int) Math.round(caveHeightNoise); - int pu = (int) (caveHeight + tunnelHeight); - int pd = (int) (caveHeight - tunnelHeight); - - if (pd > surface + 1) { - continue; - } - - if (!layer.isCanBreakSurface() && pu > surface - 3) { - continue; - } - - if ((pu > 255 && pd > 255) || (pu < 0 && pd < 0)) { - continue; - } - - if (data == null) { - ceiling = Math.max(pu, ceiling); - floor = Math.min(pu, floor); - ceiling = Math.max(pd, ceiling); - floor = Math.min(pd, floor); - - if (tunnelHeight == 1) { - ceiling = Math.max(caveHeight, ceiling); - floor = Math.min(caveHeight, floor); - } - } else { - if (dig(x, pu, z, data, fluid)) { - ceiling = Math.max(pu, ceiling); - floor = Math.min(pu, floor); - } - - if (dig(x, pd, z, data, fluid)) { - ceiling = Math.max(pd, ceiling); - floor = Math.min(pd, floor); - } - - if (tunnelHeight == 1) { - if (dig(x, caveHeight, z, data, fluid)) { - ceiling = Math.max(caveHeight, ceiling); - floor = Math.min(caveHeight, floor); - } - } - } - } - } - - if (floor >= 0 && ceiling <= 255) { - result.add(new CaveResult(floor, ceiling)); - } - } - - private Material mat(int x, int y, int z, Hunk data) { - BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0)); - - if (d != null) { - return d.getMaterial(); - } - - return Material.CAVE_AIR; - } - - public boolean dig(int x, int y, int z, Hunk data, Function caveFluid) { - Material a = mat(x, y, z, data); - Material c = mat(x, y + 1, z, data); - Material d = mat(x, y + 2, z, data); - Material e = mat(x, y + 3, z, data); - Material f = mat(x, y - 1, z, data); - BlockData b = caveFluid.apply(y); - BlockData b2 = caveFluid.apply(y + 1); - - if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) { - data.set(x, y, z, b); - data.set(x, y + 1, z, b2); - return true; - } - - return false; - } - - public boolean canAir(Material m, BlockData caveFluid) { - return (B.isSolid(m) || - (B.isDecorant(m.createBlockData())) || m.equals(Material.AIR) - || m.equals(caveFluid.getMaterial()) || - m.equals(B.getMaterial("CAVE_AIR"))) - && !m.equals(Material.BEDROCK); - } - - public boolean canWater(Material m) { - return !m.equals(Material.WATER); - } - - public boolean can(Material m) { - return B.isSolid(m) && !m.equals(Material.BEDROCK); - } -} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index fee01f68a..2878fb0d2 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -159,58 +159,54 @@ public class IrisPostModifier extends EngineAssignedModifier { // Wall Patcher IrisBiome biome = getComplex().getTrueBiomeStream().get(x, z); - if (getDimension().isPostProcessingWalls()) { - if (!biome.getWall().getPalette().isEmpty()) { - if (ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2) { - boolean brokeGround = false; - int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd)))); + if (!biome.getWall().getPalette().isEmpty()) { + if (ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2) { + boolean brokeGround = false; + int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd)))); - for (int i = h; i > h - max; i--) { - BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); + for (int i = h; i > h - max; i--) { + BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); - if (d != null) { - if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) { - if (brokeGround) { - break; - } - - continue; + if (d != null) { + if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) { + if (brokeGround) { + break; } - setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData); - brokeGround = true; + continue; } + + setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData); + brokeGround = true; } } } } // Slab - if (getDimension().isPostProcessingSlabs()) { - //@builder - if ((ha == h + 1 && isSolidNonSlab(x + 1, ha, z, currentPostX, currentPostZ, currentData)) - || (hb == h + 1 && isSolidNonSlab(x, hb, z + 1, currentPostX, currentPostZ, currentData)) - || (hc == h + 1 && isSolidNonSlab(x - 1, hc, z, currentPostX, currentPostZ, currentData)) - || (hd == h + 1 && isSolidNonSlab(x, hd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = biome.getSlab().get(rng, x, h, z, getData()); + //@builder + if ((ha == h + 1 && isSolidNonSlab(x + 1, ha, z, currentPostX, currentPostZ, currentData)) + || (hb == h + 1 && isSolidNonSlab(x, hb, z + 1, currentPostX, currentPostZ, currentData)) + || (hc == h + 1 && isSolidNonSlab(x - 1, hc, z, currentPostX, currentPostZ, currentData)) + || (hd == h + 1 && isSolidNonSlab(x, hd, z - 1, currentPostX, currentPostZ, currentData))) + //@done + { + BlockData d = biome.getSlab().get(rng, x, h, z, getData()); - if (d != null) { - boolean cancel = B.isAir(d); + if (d != null) { + boolean cancel = B.isAir(d); - if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { - cancel = true; - } + if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { + cancel = true; + } - if (isSnowLayer(x, h, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } + if (isSnowLayer(x, h, z, currentPostX, currentPostZ, currentData)) { + cancel = true; + } - if (!cancel && isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData)) { - setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData); - h++; - } + if (!cancel && isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData)) { + setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData); + h++; } } } @@ -250,141 +246,6 @@ public class IrisPostModifier extends EngineAssignedModifier { setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData); } } - - if (getDimension().isPostProcessCaves()) { - IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z); - - if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) { - if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) { - continue; - } - - int f = i.getFloor(); - int fa = nearestCaveFloor(f, x + 1, z, currentPostX, currentPostZ, currentData); - int fb = nearestCaveFloor(f, x, z + 1, currentPostX, currentPostZ, currentData); - int fc = nearestCaveFloor(f, x - 1, z, currentPostX, currentPostZ, currentData); - int fd = nearestCaveFloor(f, x, z - 1, currentPostX, currentPostZ, currentData); - int c = i.getCeiling(); - int ca = nearestCaveCeiling(c, x + 1, z, currentPostX, currentPostZ, currentData); - int cb = nearestCaveCeiling(c, x, z + 1, currentPostX, currentPostZ, currentData); - int cc = nearestCaveCeiling(c, x - 1, z, currentPostX, currentPostZ, currentData); - int cd = nearestCaveCeiling(c, x, z - 1, currentPostX, currentPostZ, currentData); - - // Cave Nibs - g = 0; - g += fa == f - 1 ? 1 : 0; - g += fb == f - 1 ? 1 : 0; - g += fc == f - 1 ? 1 : 0; - g += fd == f - 1 ? 1 : 0; - - if (g >= 4) { - BlockData bc = getPostBlock(x, f, z, currentPostX, currentPostZ, currentData); - b = getPostBlock(x, f + 1, z, currentPostX, currentPostZ, currentData); - Material m = bc.getMaterial(); - - if (m.isSolid()) { - setPostBlock(x, f, z, b, currentPostX, currentPostZ, currentData); - h--; - } - } else { - // Cave Potholes - g = 0; - g += fa == f + 1 ? 1 : 0; - g += fb == f + 1 ? 1 : 0; - g += fc == f + 1 ? 1 : 0; - g += fd == f + 1 ? 1 : 0; - - if (g >= 4) { - BlockData ba = getPostBlock(x, fa, z, currentPostX, currentPostZ, currentData); - BlockData bb = getPostBlock(x, fb, z, currentPostX, currentPostZ, currentData); - BlockData bc = getPostBlock(x, fc, z, currentPostX, currentPostZ, currentData); - BlockData bd = getPostBlock(x, fd, z, currentPostX, currentPostZ, currentData); - g = 0; - g = B.isSolid(ba) ? g + 1 : g; - g = B.isSolid(bb) ? g + 1 : g; - g = B.isSolid(bc) ? g + 1 : g; - g = B.isSolid(bd) ? g + 1 : g; - - if (g >= 4) { - setPostBlock(x, f + 1, z, getPostBlock(x, f, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData); - h++; - } - } - } - - if (getDimension().isPostProcessingSlabs()) { - //@builder - if ((fa == f + 1 && isSolidNonSlab(x + 1, fa, z, currentPostX, currentPostZ, currentData)) - || (fb == f + 1 && isSolidNonSlab(x, fb, z + 1, currentPostX, currentPostZ, currentData)) - || (fc == f + 1 && isSolidNonSlab(x - 1, fc, z, currentPostX, currentPostZ, currentData)) - || (fd == f + 1 && isSolidNonSlab(x, fd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = cave.getSlab().get(rng, x, f, z, getData()); - - if (d != null) { - boolean cancel = B.isAir(d); - - if (d.getMaterial().equals(Material.SNOW) && f + 1 <= getDimension().getFluidHeight()) { - cancel = true; - } - - if (isSnowLayer(x, f, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } - - if (!cancel && isAirOrWater(x, f + 1, z, currentPostX, currentPostZ, currentData)) { - setPostBlock(x, f + 1, z, d, currentPostX, currentPostZ, currentData); - } - } - } - - //@builder - if ((ca == c - 1 && isSolidNonSlab(x + 1, ca, z, currentPostX, currentPostZ, currentData)) - || (cb == c - 1 && isSolidNonSlab(x, cb, z + 1, currentPostX, currentPostZ, currentData)) - || (cc == c - 1 && isSolidNonSlab(x - 1, cc, z, currentPostX, currentPostZ, currentData)) - || (cd == c - 1 && isSolidNonSlab(x, cd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = cave.getSlab().get(rng, x, c, z, getData()); - - if (d != null) { - boolean cancel = B.isAir(d); - - if (!(d instanceof Slab)) { - cancel = true; - } - - if (isSnowLayer(x, c, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } - - if (!cancel && isAirOrWater(x, c, z, currentPostX, currentPostZ, currentData)) { - try { - Slab slab = (Slab) d.clone(); - slab.setType(Slab.Type.TOP); - setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); - } catch (Throwable e) { - Iris.reportError(e); - try { - Slab slab = (Slab) d.clone(); - - synchronized (slab) { - slab.setType(Slab.Type.TOP); - setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); - } - } catch (Throwable ee) { - Iris.reportError(ee); - } - } - } - } - } - } - } - } - } } private int nearestCaveFloor(int floor, int x, int z, int currentPostX, int currentPostZ, Hunk currentData) { diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java index 4994393f9..ec9800ba7 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java @@ -27,6 +27,7 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.block.IrisBlockDrops; +import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; @@ -74,6 +75,10 @@ public class IrisBiome extends IrisRegistrant implements IRare { @Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.") private String name = "A Biome"; + @Desc("Register caves to generate") + @ArrayType(min = 1, type = IrisCavePlacer.class) + private KList caves = new KList<>(); + @ArrayType(min = 1, type = IrisBiomeCustom.class) @Desc("If the biome type custom is defined, specify this") private KList customDerivitives; diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 08050272d..d759c6ae2 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -32,6 +32,8 @@ import com.volmit.iris.engine.object.carve.IrisCarveLayer; import com.volmit.iris.engine.object.carve.IrisCaveFluid; import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.engine.object.carve.IrisCaverns; +import com.volmit.iris.engine.object.cave.IrisCave; +import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -175,9 +177,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("The placement style of biomes") private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("Generate caves or not.") - private boolean caves = true; - @Desc("Instead of filling objects with air, fills them with cobweb so you can see them") private boolean debugSmartBore = false; @@ -210,9 +209,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Add painted walls in post processing") private boolean postProcessingWalls = true; - @Desc("Use post processing for caves or not") - private boolean postProcessCaves = true; - @Desc("The world environment") private Environment environment = Environment.NORMAL; @@ -305,10 +301,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Overlay additional noise on top of the interoplated terrain.") private KList overlayNoise = new KList<>(); - @ArrayType(min = 1, type = IrisCaveLayer.class) - @Desc("Define cave layers") - private KList caveLayers = new KList<>(); - @ArrayType(min = 1, type = IrisCarveLayer.class) @Desc("Define carve layers") private KList carveLayers = new KList<>(); @@ -330,6 +322,10 @@ public class IrisDimension extends IrisRegistrant { @Desc("Cartographer map trade overrides") private IrisVillagerOverride patchCartographers = new IrisVillagerOverride().setDisableTrade(false); + @Desc("Register caves to generate") + @ArrayType(min = 1, type = IrisCavePlacer.class) + private KList caves = new KList<>(); + private final transient AtomicCache parallaxSize = new AtomicCache<>(); private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java index 3ae2d9d39..02b1015fb 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; @@ -83,23 +82,8 @@ public class IrisEntitySpawn implements IRare { int h = gen.getHeight(x, z, true); int hf = gen.getHeight(x, z, false); Location l = switch (getReferenceSpawner().getGroup()) { - case NORMAL -> new Location(c.getWorld(), x, hf + 1, z); - case CAVE -> { - IrisComplex comp = gen.getComplex(); - IrisBiome cave = comp.getCaveBiomeStream().get(x, z); - KList r = new KList<>(); - if (cave != null) { - for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) { - if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) { - continue; - } - - r.add(new Location(c.getWorld(), x, i.getFloor(), z)); - } - } - - yield r.getRandom(rng); - } + case NORMAL, CAVE -> new Location(c.getWorld(), x, hf + 1, z); + // TODO HANDLE CAVES case UNDERWATER, BEACH -> new Location(c.getWorld(), x, rng.i(h + 1, hf), z); }; diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java index c24ea2ab8..5c6904005 100644 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java @@ -27,6 +27,7 @@ import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockDrops; +import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -69,6 +70,10 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("The name of the region") private String name = "A Region"; + @Desc("Register caves to generate") + @ArrayType(min = 1, type = IrisCavePlacer.class) + private KList caves = new KList<>(); + @ArrayType(min = 1, type = IrisJigsawStructurePlacement.class) @Desc("Jigsaw structures") private KList jigsawStructures = new KList<>(); diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 351882140..409a8b14e 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -24,7 +24,8 @@ public enum MantleFlag { OBJECT, UPDATE, JIGSAW, - FEATURE; + FEATURE, + CAVE; static StateList getStateList() { return new StateList(MantleFlag.values()); From f3931567f96291b195dc4fe2bf5cdb6946f3bfcf Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Fri, 20 Aug 2021 01:34:14 -0400 Subject: [PATCH 11/39] Revert "Test" This reverts commit 154adafbcbf0391ac3d82246b18e5d8d92f0a0d6. --- src/main/java/com/volmit/iris/Iris.java | 2 +- .../com/volmit/iris/core/gui/VisionGUI.java | 8 +- .../core/gui/components/IrisRenderer.java | 4 +- .../com/volmit/iris/engine/IrisComplex.java | 44 ++- .../com/volmit/iris/engine/IrisEngine.java | 46 ++- .../volmit/iris/engine/IrisEngineMantle.java | 25 +- .../engine/actuator/IrisDecorantActuator.java | 50 +++- .../volmit/iris/engine/framework/Engine.java | 8 +- .../components/MantleCaveComponent.java | 96 ------- .../engine/modifier/IrisCaveModifier.java | 261 ++++++++++++++++++ .../engine/modifier/IrisPostModifier.java | 205 +++++++++++--- .../iris/engine/object/biome/IrisBiome.java | 5 - .../object/dimensional/IrisDimension.java | 16 +- .../engine/object/entity/IrisEntitySpawn.java | 20 +- .../engine/object/regional/IrisRegion.java | 5 - .../volmit/iris/util/mantle/MantleFlag.java | 3 +- 16 files changed, 585 insertions(+), 213 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java create mode 100644 src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index d0c360310..fd93d97a8 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -498,7 +498,7 @@ public class Iris extends VolmitPlugin implements Listener { } catch (Throwable e) { try { System.out.println(instance.getTag() + string.replaceAll("(<([^>]+)>)", "")); - } catch (Throwable ee) { + } catch (Throwable ignored1) { } } diff --git a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java index d46033ccc..4cb5c1d04 100644 --- a/src/main/java/com/volmit/iris/core/gui/VisionGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/VisionGUI.java @@ -192,8 +192,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> engine.getComplex().getTrueBiomeStreamNoFeatures().get(x, z).getColor(engine, currentType).getRGB(); case BIOME_LAND -> colorFunction = (x, z) -> engine.getComplex().getLandBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); case BIOME_SEA -> colorFunction = (x, z) -> engine.getComplex().getSeaBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); - // TODO: CAVE - case REGION, CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> engine.getComplex().getRegionStream().get(x, z).getColor(engine.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> engine.getComplex().getCaveBiomeStream().get(x, z).getColor(engine, currentType).getRGB(); case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(engine.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } @@ -696,8 +696,8 @@ public class VisionGUI extends JPanel implements MouseWheelListener, KeyListener case BIOME, LAYER_LOAD, DECORATOR_LOAD, OBJECT_LOAD, HEIGHT -> r = complex.getTrueBiomeStreamNoFeatures().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); case BIOME_LAND -> r = complex.getLandBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); case BIOME_SEA -> r = complex.getSeaBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); - // TODO: CAVE - case REGION, CAVE_LAND -> r = complex.getRegionStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); + case REGION -> r = complex.getRegionStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); + case CAVE_LAND -> r = complex.getCaveBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode(); } notify("Opening " + r.getPath() + " in VSCode"); diff --git a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index 45a2c9bd5..944b4af3a 100644 --- a/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -41,8 +41,8 @@ public class IrisRenderer { case BIOME, DECORATOR_LOAD, OBJECT_LOAD, LAYER_LOAD -> colorFunction = (x, z) -> renderer.getComplex().getTrueBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); case BIOME_LAND -> colorFunction = (x, z) -> renderer.getComplex().getLandBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); case BIOME_SEA -> colorFunction = (x, z) -> renderer.getComplex().getSeaBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); - // TODO: CAVE - case REGION,CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); + case REGION -> colorFunction = (x, z) -> renderer.getComplex().getRegionStream().get(x, z).getColor(renderer.getComplex(), currentType).getRGB(); + case CAVE_LAND -> colorFunction = (x, z) -> renderer.getComplex().getCaveBiomeStream().get(x, z).getColor(renderer, currentType).getRGB(); case HEIGHT -> colorFunction = (x, z) -> Color.getHSBColor(renderer.getComplex().getHeightStream().get(x, z).floatValue(), 100, 100).getRGB(); } diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 2ba489c42..43a11c3d3 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -24,6 +24,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; @@ -69,6 +70,7 @@ public class IrisComplex implements DataProvider { private ProceduralStream islandDepthStream; private ProceduralStream bridgeStream; private ProceduralStream landBiomeStream; + private ProceduralStream caveBiomeStream; private ProceduralStream seaBiomeStream; private ProceduralStream shoreBiomeStream; private ProceduralStream baseBiomeStream; @@ -103,8 +105,9 @@ public class IrisComplex implements DataProvider { public ProceduralStream getBiomeStream(InferredType type) { switch (type) { case CAVE: + return caveBiomeStream; case LAND: - return landBiomeStream; // TODO??? + return landBiomeStream; case SEA: return seaBiomeStream; case SHORE: @@ -120,6 +123,10 @@ public class IrisComplex implements DataProvider { } public IrisComplex(Engine engine) { + this(engine, false); + } + + public IrisComplex(Engine engine, boolean simple) { int cacheSize = 131072; IrisBiome emptyBiome = new IrisBiome(); UUID focusUUID = UUID.nameUUIDFromBytes("focus".getBytes()); @@ -166,6 +173,21 @@ public class IrisComplex implements DataProvider { islandHeightStream = regionIdentityStream.style(rng.nextParallelRNG(330466), engine.getDimension().getIslandMode().getHeight(), data); islandDepthStream = engine.getDimension().getIslandMode().getIslandDepth().stream(rng.nextParallelRNG(-39578888), data); regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L)); + caveBiomeStream = regionStream.convert((r) + -> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream() + .zoom(r.getCaveBiomeZoom()) + .selectRarity(r.getCaveBiomes(), (i) -> data.getBiomeLoader().load(i)) + .onNull("") + .convertCached((s) -> { + if (s.isEmpty()) { + return emptyBiome; + } + + return data.getBiomeLoader().load(s) + .setInferredType(InferredType.CAVE); + }) + ).convertAware2D(ProceduralStream::get).cache2D(cacheSize); + inferredStreams.put(InferredType.CAVE, caveBiomeStream); landBiomeStream = regionStream.convert((r) -> engine.getDimension().getLandBiomeStyle().create(rng.nextParallelRNG(InferredType.LAND.ordinal()), getData()).stream() .zoom(r.getLandBiomeZoom()) @@ -174,7 +196,6 @@ public class IrisComplex implements DataProvider { .setInferredType(InferredType.LAND)) ).convertAware2D(ProceduralStream::get) .cache2D(cacheSize); - inferredStreams.put(InferredType.CAVE, landBiomeStream); // TODO: CAVE inferredStreams.put(InferredType.LAND, landBiomeStream); seaBiomeStream = regionStream.convert((r) -> engine.getDimension().getSeaBiomeStyle().create(rng.nextParallelRNG(InferredType.SEA.ordinal()), getData()).stream() @@ -297,6 +318,10 @@ public class IrisComplex implements DataProvider { .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D(cacheSize); terrainCeilingDecoration = trueBiomeStream .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D(cacheSize); + terrainCaveSurfaceDecoration = caveBiomeStream + .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.NONE)).cache2D(cacheSize); + terrainCaveCeilingDecoration = caveBiomeStream + .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.CEILING)).cache2D(cacheSize); shoreSurfaceDecoration = trueBiomeStream .convertAware2D((b, xx, zz) -> decorateFor(b, xx, zz, IrisDecorationPart.SHORE_LINE)).cache2D(cacheSize); seaSurfaceDecoration = trueBiomeStream @@ -319,6 +344,21 @@ public class IrisComplex implements DataProvider { } } + if (engine.getDimension().isCaves()) { + KList caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null); + boolean again = true; + + while (again) { + again = false; + for (CaveResult i : caves) { + if (i.getCeiling() > m && i.getFloor() < m) { + m = i.getFloor(); + again = true; + } + } + } + } + return m; }, Interpolated.INT).cache2D(cacheSize); baseBiomeIDStream = trueBiomeStream.convertAware2D((b, x, z) -> { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 0bc3fc270..cb973fc0c 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -64,7 +64,6 @@ import org.bukkit.generator.BlockPopulator; import java.io.File; import java.io.IOException; import java.util.Random; -import java.util.Stack; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; @@ -102,6 +101,7 @@ public class IrisEngine extends BlockPopulator implements Engine { private EngineActuator decorantActuator; private EngineActuator biomeActuator; private EngineModifier depositModifier; + private EngineModifier caveModifier; private EngineModifier ravineModifier; private EngineModifier postModifier; private final AtomicCache engineData = new AtomicCache<>(); @@ -151,35 +151,27 @@ public class IrisEngine extends BlockPopulator implements Engine { biomeActuator.close(); depositModifier.close(); ravineModifier.close(); + caveModifier.close(); postModifier.close(); effects.close(); } - private void setupEngine() { - try { - cacheId = RNG.r.nextInt(); - worldManager = new IrisWorldManager(this); - complex = new IrisComplex(this); - execution = new IrisExecutionEnvironment(this); - terrainNormalActuator = new IrisTerrainNormalActuator(this); - terrainIslandActuator = new IrisTerrainIslandActuator(this); - decorantActuator = new IrisDecorantActuator(this); - biomeActuator = new IrisBiomeActuator(this); - depositModifier = new IrisDepositModifier(this); - ravineModifier = new IrisRavineModifier(this); - postModifier = new IrisPostModifier(this); - effects = new IrisEngineEffects(this); - J.a(this::computeBiomeMaxes); - } catch (Throwable e) - { - Iris.error("FATAL: Engine load failure!"); - e.printStackTrace(); - - if(isStudio()) - { - System.exit(0); - } - } + private void setupEngine() + { + cacheId = RNG.r.nextInt(); + worldManager = new IrisWorldManager(this); + complex = new IrisComplex(this); + execution = new IrisExecutionEnvironment(this); + terrainNormalActuator = new IrisTerrainNormalActuator(this); + terrainIslandActuator = new IrisTerrainIslandActuator(this); + decorantActuator = new IrisDecorantActuator(this); + biomeActuator = new IrisBiomeActuator(this); + depositModifier = new IrisDepositModifier(this); + ravineModifier = new IrisRavineModifier(this); + caveModifier = new IrisCaveModifier(this); + postModifier = new IrisPostModifier(this); + effects = new IrisEngineEffects(this); + J.a(this::computeBiomeMaxes); } @Override @@ -340,6 +332,7 @@ public class IrisEngine extends BlockPopulator implements Engine { getBiomeActuator().close(); getDepositModifier().close(); getRavineModifier().close(); + getCaveModifier().close(); getPostModifier().close(); getMantle().close(); getComplex().close(); @@ -419,6 +412,7 @@ public class IrisEngine extends BlockPopulator implements Engine { getMantle().generateMatter(x >> 4, z >> 4, multicore); getTerrainActuator().actuate(x, z, vblocks, multicore); getBiomeActuator().actuate(x, z, vbiomes, multicore); + getCaveModifier().modify(x, z, vblocks, multicore); getRavineModifier().modify(x, z, vblocks, multicore); getPostModifier().modify(x, z, vblocks, multicore); getDecorantActuator().actuate(x, z, blocks, multicore); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index d520f886a..132056578 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -22,13 +22,10 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.MantleComponent; -import com.volmit.iris.engine.mantle.components.MantleCaveComponent; import com.volmit.iris.engine.mantle.components.MantleFeatureComponent; import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.cave.IrisCave; -import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; @@ -66,7 +63,6 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); - registerComponent(new MantleCaveComponent(this)); } @Override @@ -135,7 +131,6 @@ public class IrisEngineMantle implements EngineMantle { KMap> scalars = new KMap<>(); int x = xg.get(); int z = zg.get(); - int s = 0; if (getEngine().getDimension().isUseMantle()) { KList r = getAllRegions(); @@ -153,11 +148,6 @@ public class IrisEngineMantle implements EngineMantle { for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) { jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension()); } - - for(IrisCavePlacer j : i.getCaves()) - { - s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); - } } for (IrisRegion i : r) { @@ -172,16 +162,6 @@ public class IrisEngineMantle implements EngineMantle { for (IrisJigsawStructurePlacement j : i.getJigsawStructures()) { jig = Math.max(jig, getData().getJigsawStructureLoader().load(j.getStructure()).getMaxDimension()); } - - for(IrisCavePlacer j : i.getCaves()) - { - s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); - } - } - - for(IrisCavePlacer j : getDimension().getCaves()) - { - s = Math.max(s, j.getRealCave(getData()).getWorm().getMaxDistance()); } for (IrisJigsawStructurePlacement j : getEngine().getDimension().getJigsawStructures()) { @@ -285,9 +265,6 @@ public class IrisEngineMantle implements EngineMantle { x = xg.get(); z = zg.get(); - x = Math.max(s, x); - z = Math.max(s, z); - for (IrisDepositGenerator i : getEngine().getDimension().getDeposits()) { int max = i.getMaxDimension(); x = Math.max(max, x); @@ -313,7 +290,7 @@ public class IrisEngineMantle implements EngineMantle { return 0; } - x = Math.max(x, z); + x = Math.max(z, x); int u = x; int v = computeFeatureRange(); x = Math.max(jig, x); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index e86b150fc..744f30048 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -41,6 +41,7 @@ import java.util.function.Predicate; public class IrisDecorantActuator extends EngineAssignedActuator { private static final Predicate PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA); + private final BiPredicate PREDICATE_CAVELIQUID; private final RNG rng; @Getter private final EngineDecorator surfaceDecorator; @@ -63,6 +64,22 @@ public class IrisDecorantActuator extends EngineAssignedActuator { seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine()); shoreLineDecorator = new IrisShoreLineDecorator(getEngine()); seaFloorDecorator = new IrisSeaFloorDecorator(getEngine()); + + PREDICATE_CAVELIQUID = (b, y) -> { + for (IrisCaveLayer layer : getEngine().getDimension().getCaveLayers()) { + if (!layer.getFluid().hasFluid(getData())) { + continue; + } + + if (layer.getFluid().isInverseHeight() && y >= layer.getFluid().getFluidHeight()) { + if (b.matches(layer.getFluid().getFluid(getData()))) return true; + } else if (!layer.getFluid().isInverseHeight() && y <= layer.getFluid().getFluidHeight()) { + if (b.matches(layer.getFluid().getFluid(getData()))) return true; + } + } + return false; + }; + } @BlockCoordinates @@ -82,7 +99,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { int height; int realX = (int) Math.round(modX(x + finalI)); int realZ; - IrisBiome biome; + IrisBiome biome, cave; for (int j=0; j < output.getDepth(); j++) { boolean solid, liquid; int emptyFor = 0; @@ -91,8 +108,9 @@ public class IrisDecorantActuator extends EngineAssignedActuator { realZ = (int) Math.round(modZ(z + j)); height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); biome = getComplex().getTrueBiomeStream().get(realX, realZ); + cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : null; - if (biome.getDecorators().isEmpty()) { + if (biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { continue; } @@ -115,6 +133,32 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); + + + if (cave != null && cave.getDecorators().isNotEmpty()) { + for (int k = height; k > 0; k--) { + solid = PREDICATE_SOLID.test(output.get(finalI, k, j)); + liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1); + + if (solid) { + if (emptyFor > 0) { + if (liquid) { + getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); + getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); + } else { + getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); + getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); + } + emptyFor = 0; + liquidFor = 0; + } + lastSolid = k; + } else { + emptyFor++; + if (liquid) liquidFor++; + } + } + } } }); } @@ -125,6 +169,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } private boolean shouldRayDecorate() { - return getEngine().getDimension().isCarving() || getEngine().getDimension().isRavines(); + return getEngine().getDimension().isCarving() || getEngine().getDimension().isCaves() || getEngine().getDimension().isRavines(); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 71d770393..0a3e8e02b 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -92,6 +92,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat EngineActuator getBiomeActuator(); + EngineModifier getCaveModifier(); + EngineModifier getRavineModifier(); EngineModifier getDepositModifier(); @@ -192,7 +194,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @BlockCoordinates default IrisBiome getCaveBiome(int x, int z) { - return getComplex().getLandBiomeStream().get(x, z); // TODO!!!!!!!!!! + return getComplex().getCaveBiomeStream().get(x, z); } @BlockCoordinates @@ -354,11 +356,13 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } IrisRegion region = getComplex().getRegionStream().get(rx, rz); IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz); + IrisBiome biomeUnder = b.getY() < he ? getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface; KList tables = new KList<>(); - double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier(); + double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier(); injectTables(tables, getDimension().getLoot()); injectTables(tables, region.getLoot()); injectTables(tables, biomeSurface.getLoot()); + injectTables(tables, biomeUnder.getLoot()); if (tables.isNotEmpty()) { int target = (int) Math.round(tables.size() * multiplier); diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java deleted file mode 100644 index e72c74b71..000000000 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleCaveComponent.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.mantle.components; - -import com.volmit.iris.Iris; -import com.volmit.iris.core.project.loader.IrisData; -import com.volmit.iris.engine.data.cache.Cache; -import com.volmit.iris.engine.jigsaw.PlannedStructure; -import com.volmit.iris.engine.mantle.EngineMantle; -import com.volmit.iris.engine.mantle.IrisMantleComponent; -import com.volmit.iris.engine.object.basic.IrisPosition; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.engine.object.cave.IrisCave; -import com.volmit.iris.engine.object.cave.IrisCavePlacer; -import com.volmit.iris.engine.object.dimensional.IrisDimension; -import com.volmit.iris.engine.object.feature.IrisFeaturePositional; -import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; -import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; -import com.volmit.iris.engine.object.regional.IrisRegion; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.documentation.BlockCoordinates; -import com.volmit.iris.util.documentation.ChunkCoordinates; -import com.volmit.iris.util.mantle.MantleFlag; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.math.RNG; -import org.bukkit.util.Vector; - -import java.util.List; -import java.util.function.Consumer; - -public class MantleCaveComponent extends IrisMantleComponent { - private final RNG crng; - public MantleCaveComponent(EngineMantle engineMantle) { - super(engineMantle, MantleFlag.CAVE); - crng = new RNG(getEngineMantle().getEngine().getWorld().seed() - 229333333); - } - - @Override - public void generateLayer(int x, int z, Consumer post) { - RNG rng = new RNG(Cache.key(x, z) + seed()); - int xxx = (x << 4) + rng.i(16); - int zzz = (z << 4) + rng.i(16); - - IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); - - for(IrisCavePlacer i : biome.getCaves()) - { - if(rng.nextInt(i.getRarity()) == 0) - { - place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); - return; - } - } - - IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); - - for(IrisCavePlacer i : region.getCaves()) - { - if(rng.nextInt(i.getRarity()) == 0) - { - place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); - return; - } - } - - for(IrisCavePlacer i : getDimension().getCaves()) - { - if(rng.nextInt(i.getRarity()) == 0) - { - place(i, xxx, getEngineMantle().trueHeight(xxx, zzz), zzz); - return; - } - } - } - - private void place(IrisCavePlacer cave, int x, int y, int z) { - cave.generateCave(getMantle(), crng, getData(), x, y, z); - } -} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java new file mode 100644 index 000000000..13ab2cd30 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java @@ -0,0 +1,261 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.modifier; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.EngineAssignedModifier; +import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.carve.IrisCaveLayer; +import com.volmit.iris.engine.object.common.CaveResult; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.FastNoiseDouble; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; + +import java.util.function.Function; + +public class IrisCaveModifier extends EngineAssignedModifier { + public static final BlockData CAVE_AIR = B.get("CAVE_AIR"); + public static final BlockData AIR = B.get("AIR"); + private static final KList EMPTY = new KList<>(); + private final FastNoiseDouble gg; + private final RNG rng; + + public IrisCaveModifier(Engine engine) { + super(engine, "Cave"); + rng = new RNG(engine.getWorld().seed() + 28934555); + gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax()); + } + + @Override + public void onModify(int x, int z, Hunk a, boolean multicore) { + if (!getDimension().isCaves()) { + return; + } + + PrecisionStopwatch p = PrecisionStopwatch.start(); + if (multicore) { + BurstExecutor e = getEngine().burst().burst(a.getWidth()); + for (int i = 0; i < a.getWidth(); i++) { + int finalI = i; + e.queue(() -> modifySliver(x, z, finalI, a)); + } + + e.complete(); + } else { + for (int i = 0; i < a.getWidth(); i++) { + modifySliver(x, z, i, a); + } + } + + getEngine().getMetrics().getCave().put(p.getMilliseconds()); + } + + public void modifySliver(int x, int z, int finalI, Hunk a) { + for (int j = 0; j < a.getDepth(); j++) { + KList caves = genCaves(x + finalI, z + j, finalI, j, a); + int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j)); + if (caves != null && caves.isNotEmpty()) { + IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j); + + if (cave == null) { + continue; + } + + for (CaveResult cl : caves) { + if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { + continue; + } + + KList floor = cave.generateLayers(x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex()); + KList ceiling = cave.generateLayers(x + finalI + 656, z + j - 656, rng, + he - cl.getCeiling(), + he - cl.getCeiling(), getData(), getComplex()); + + for (int g = 0; g < floor.size(); g++) { + a.set(finalI, cl.getFloor() - g, j, floor.get(g)); + } + + for (int g = ceiling.size() - 1; g > 0; g--) { + a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g)); + } + } + } + } + } + + public KList genCaves(double wxx, double wzz) { + return genCaves(wxx, wzz, 0, 0, null); + } + + public KList genCaves(double wxx, double wzz, int x, int z, Hunk data) { + if (!getDimension().isCaves()) { + return EMPTY; + } + + KList result = new KList<>(); + gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular); + gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub); + gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural); + + for (int i = 0; i < getDimension().getCaveLayers().size(); i++) { + IrisCaveLayer layer = getDimension().getCaveLayers().get(i); + generateCave(result, wxx, wzz, x, z, data, layer, i); + } + + return result; + } + + public void generateCave(KList result, double wxx, double wzz, int x, int z, Hunk data, IrisCaveLayer layer, int seed) { + double scale = layer.getCaveZoom(); + Function fluid = (height) -> + { + if (!layer.getFluid().hasFluid(getData())) { + return CAVE_AIR; + } + + if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) { + return layer.getFluid().getFluid(getData()); + } else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) { + return layer.getFluid().getFluid(getData()); + } + + return CAVE_AIR; + }; + + int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz)); + double wx = wxx + layer.getHorizontalSlope().get(rng, getData(), wxx, wzz); + double wz = wzz + layer.getHorizontalSlope().get(rng, getData(), -wzz, -wxx); + double baseWidth = (14 * scale); + double distanceCheck = 0.0132 * baseWidth; + double distanceTake = 0.0022 * baseWidth; + double caveHeightNoise = layer.getVerticalSlope().get(rng, getData(), wxx, wzz); + + if (caveHeightNoise > 259 || caveHeightNoise < -1) { + return; + } + + // TODO: WARNING HEIGHT + int ceiling = -256; + int floor = 512; + + for (double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) { + double distance = (gg.GetCellular(((wx + (10000 * seed)) / layer.getCaveZoom()), ((wz - (10000 * seed)) / layer.getCaveZoom())) + 1D) / 2D; + if (distance < distanceCheck - (tunnelHeight * distanceTake)) { + int caveHeight = (int) Math.round(caveHeightNoise); + int pu = (int) (caveHeight + tunnelHeight); + int pd = (int) (caveHeight - tunnelHeight); + + if (pd > surface + 1) { + continue; + } + + if (!layer.isCanBreakSurface() && pu > surface - 3) { + continue; + } + + if ((pu > 255 && pd > 255) || (pu < 0 && pd < 0)) { + continue; + } + + if (data == null) { + ceiling = Math.max(pu, ceiling); + floor = Math.min(pu, floor); + ceiling = Math.max(pd, ceiling); + floor = Math.min(pd, floor); + + if (tunnelHeight == 1) { + ceiling = Math.max(caveHeight, ceiling); + floor = Math.min(caveHeight, floor); + } + } else { + if (dig(x, pu, z, data, fluid)) { + ceiling = Math.max(pu, ceiling); + floor = Math.min(pu, floor); + } + + if (dig(x, pd, z, data, fluid)) { + ceiling = Math.max(pd, ceiling); + floor = Math.min(pd, floor); + } + + if (tunnelHeight == 1) { + if (dig(x, caveHeight, z, data, fluid)) { + ceiling = Math.max(caveHeight, ceiling); + floor = Math.min(caveHeight, floor); + } + } + } + } + } + + if (floor >= 0 && ceiling <= 255) { + result.add(new CaveResult(floor, ceiling)); + } + } + + private Material mat(int x, int y, int z, Hunk data) { + BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0)); + + if (d != null) { + return d.getMaterial(); + } + + return Material.CAVE_AIR; + } + + public boolean dig(int x, int y, int z, Hunk data, Function caveFluid) { + Material a = mat(x, y, z, data); + Material c = mat(x, y + 1, z, data); + Material d = mat(x, y + 2, z, data); + Material e = mat(x, y + 3, z, data); + Material f = mat(x, y - 1, z, data); + BlockData b = caveFluid.apply(y); + BlockData b2 = caveFluid.apply(y + 1); + + if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) { + data.set(x, y, z, b); + data.set(x, y + 1, z, b2); + return true; + } + + return false; + } + + public boolean canAir(Material m, BlockData caveFluid) { + return (B.isSolid(m) || + (B.isDecorant(m.createBlockData())) || m.equals(Material.AIR) + || m.equals(caveFluid.getMaterial()) || + m.equals(B.getMaterial("CAVE_AIR"))) + && !m.equals(Material.BEDROCK); + } + + public boolean canWater(Material m) { + return !m.equals(Material.WATER); + } + + public boolean can(Material m) { + return B.isSolid(m) && !m.equals(Material.BEDROCK); + } +} diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 2878fb0d2..fee01f68a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -159,54 +159,58 @@ public class IrisPostModifier extends EngineAssignedModifier { // Wall Patcher IrisBiome biome = getComplex().getTrueBiomeStream().get(x, z); - if (!biome.getWall().getPalette().isEmpty()) { - if (ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2) { - boolean brokeGround = false; - int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd)))); + if (getDimension().isPostProcessingWalls()) { + if (!biome.getWall().getPalette().isEmpty()) { + if (ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2) { + boolean brokeGround = false; + int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd)))); - for (int i = h; i > h - max; i--) { - BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); + for (int i = h; i > h - max; i--) { + BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); - if (d != null) { - if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) { - if (brokeGround) { - break; + if (d != null) { + if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) { + if (brokeGround) { + break; + } + + continue; } - continue; + setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData); + brokeGround = true; } - - setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData); - brokeGround = true; } } } } // Slab - //@builder - if ((ha == h + 1 && isSolidNonSlab(x + 1, ha, z, currentPostX, currentPostZ, currentData)) - || (hb == h + 1 && isSolidNonSlab(x, hb, z + 1, currentPostX, currentPostZ, currentData)) - || (hc == h + 1 && isSolidNonSlab(x - 1, hc, z, currentPostX, currentPostZ, currentData)) - || (hd == h + 1 && isSolidNonSlab(x, hd, z - 1, currentPostX, currentPostZ, currentData))) - //@done - { - BlockData d = biome.getSlab().get(rng, x, h, z, getData()); + if (getDimension().isPostProcessingSlabs()) { + //@builder + if ((ha == h + 1 && isSolidNonSlab(x + 1, ha, z, currentPostX, currentPostZ, currentData)) + || (hb == h + 1 && isSolidNonSlab(x, hb, z + 1, currentPostX, currentPostZ, currentData)) + || (hc == h + 1 && isSolidNonSlab(x - 1, hc, z, currentPostX, currentPostZ, currentData)) + || (hd == h + 1 && isSolidNonSlab(x, hd, z - 1, currentPostX, currentPostZ, currentData))) + //@done + { + BlockData d = biome.getSlab().get(rng, x, h, z, getData()); - if (d != null) { - boolean cancel = B.isAir(d); + if (d != null) { + boolean cancel = B.isAir(d); - if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { - cancel = true; - } + if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { + cancel = true; + } - if (isSnowLayer(x, h, z, currentPostX, currentPostZ, currentData)) { - cancel = true; - } + if (isSnowLayer(x, h, z, currentPostX, currentPostZ, currentData)) { + cancel = true; + } - if (!cancel && isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData)) { - setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData); - h++; + if (!cancel && isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData)) { + setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData); + h++; + } } } } @@ -246,6 +250,141 @@ public class IrisPostModifier extends EngineAssignedModifier { setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData); } } + + if (getDimension().isPostProcessCaves()) { + IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z); + + if (cave != null) { + for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) { + if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) { + continue; + } + + int f = i.getFloor(); + int fa = nearestCaveFloor(f, x + 1, z, currentPostX, currentPostZ, currentData); + int fb = nearestCaveFloor(f, x, z + 1, currentPostX, currentPostZ, currentData); + int fc = nearestCaveFloor(f, x - 1, z, currentPostX, currentPostZ, currentData); + int fd = nearestCaveFloor(f, x, z - 1, currentPostX, currentPostZ, currentData); + int c = i.getCeiling(); + int ca = nearestCaveCeiling(c, x + 1, z, currentPostX, currentPostZ, currentData); + int cb = nearestCaveCeiling(c, x, z + 1, currentPostX, currentPostZ, currentData); + int cc = nearestCaveCeiling(c, x - 1, z, currentPostX, currentPostZ, currentData); + int cd = nearestCaveCeiling(c, x, z - 1, currentPostX, currentPostZ, currentData); + + // Cave Nibs + g = 0; + g += fa == f - 1 ? 1 : 0; + g += fb == f - 1 ? 1 : 0; + g += fc == f - 1 ? 1 : 0; + g += fd == f - 1 ? 1 : 0; + + if (g >= 4) { + BlockData bc = getPostBlock(x, f, z, currentPostX, currentPostZ, currentData); + b = getPostBlock(x, f + 1, z, currentPostX, currentPostZ, currentData); + Material m = bc.getMaterial(); + + if (m.isSolid()) { + setPostBlock(x, f, z, b, currentPostX, currentPostZ, currentData); + h--; + } + } else { + // Cave Potholes + g = 0; + g += fa == f + 1 ? 1 : 0; + g += fb == f + 1 ? 1 : 0; + g += fc == f + 1 ? 1 : 0; + g += fd == f + 1 ? 1 : 0; + + if (g >= 4) { + BlockData ba = getPostBlock(x, fa, z, currentPostX, currentPostZ, currentData); + BlockData bb = getPostBlock(x, fb, z, currentPostX, currentPostZ, currentData); + BlockData bc = getPostBlock(x, fc, z, currentPostX, currentPostZ, currentData); + BlockData bd = getPostBlock(x, fd, z, currentPostX, currentPostZ, currentData); + g = 0; + g = B.isSolid(ba) ? g + 1 : g; + g = B.isSolid(bb) ? g + 1 : g; + g = B.isSolid(bc) ? g + 1 : g; + g = B.isSolid(bd) ? g + 1 : g; + + if (g >= 4) { + setPostBlock(x, f + 1, z, getPostBlock(x, f, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData); + h++; + } + } + } + + if (getDimension().isPostProcessingSlabs()) { + //@builder + if ((fa == f + 1 && isSolidNonSlab(x + 1, fa, z, currentPostX, currentPostZ, currentData)) + || (fb == f + 1 && isSolidNonSlab(x, fb, z + 1, currentPostX, currentPostZ, currentData)) + || (fc == f + 1 && isSolidNonSlab(x - 1, fc, z, currentPostX, currentPostZ, currentData)) + || (fd == f + 1 && isSolidNonSlab(x, fd, z - 1, currentPostX, currentPostZ, currentData))) + //@done + { + BlockData d = cave.getSlab().get(rng, x, f, z, getData()); + + if (d != null) { + boolean cancel = B.isAir(d); + + if (d.getMaterial().equals(Material.SNOW) && f + 1 <= getDimension().getFluidHeight()) { + cancel = true; + } + + if (isSnowLayer(x, f, z, currentPostX, currentPostZ, currentData)) { + cancel = true; + } + + if (!cancel && isAirOrWater(x, f + 1, z, currentPostX, currentPostZ, currentData)) { + setPostBlock(x, f + 1, z, d, currentPostX, currentPostZ, currentData); + } + } + } + + //@builder + if ((ca == c - 1 && isSolidNonSlab(x + 1, ca, z, currentPostX, currentPostZ, currentData)) + || (cb == c - 1 && isSolidNonSlab(x, cb, z + 1, currentPostX, currentPostZ, currentData)) + || (cc == c - 1 && isSolidNonSlab(x - 1, cc, z, currentPostX, currentPostZ, currentData)) + || (cd == c - 1 && isSolidNonSlab(x, cd, z - 1, currentPostX, currentPostZ, currentData))) + //@done + { + BlockData d = cave.getSlab().get(rng, x, c, z, getData()); + + if (d != null) { + boolean cancel = B.isAir(d); + + if (!(d instanceof Slab)) { + cancel = true; + } + + if (isSnowLayer(x, c, z, currentPostX, currentPostZ, currentData)) { + cancel = true; + } + + if (!cancel && isAirOrWater(x, c, z, currentPostX, currentPostZ, currentData)) { + try { + Slab slab = (Slab) d.clone(); + slab.setType(Slab.Type.TOP); + setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); + } catch (Throwable e) { + Iris.reportError(e); + try { + Slab slab = (Slab) d.clone(); + + synchronized (slab) { + slab.setType(Slab.Type.TOP); + setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData); + } + } catch (Throwable ee) { + Iris.reportError(ee); + } + } + } + } + } + } + } + } + } } private int nearestCaveFloor(int floor, int x, int z, int currentPostX, int currentPostZ, Hunk currentData) { diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java index ec9800ba7..4994393f9 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java @@ -27,7 +27,6 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.block.IrisBlockDrops; -import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; @@ -75,10 +74,6 @@ public class IrisBiome extends IrisRegistrant implements IRare { @Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.") private String name = "A Biome"; - @Desc("Register caves to generate") - @ArrayType(min = 1, type = IrisCavePlacer.class) - private KList caves = new KList<>(); - @ArrayType(min = 1, type = IrisBiomeCustom.class) @Desc("If the biome type custom is defined, specify this") private KList customDerivitives; diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index d759c6ae2..08050272d 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -32,8 +32,6 @@ import com.volmit.iris.engine.object.carve.IrisCarveLayer; import com.volmit.iris.engine.object.carve.IrisCaveFluid; import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.engine.object.carve.IrisCaverns; -import com.volmit.iris.engine.object.cave.IrisCave; -import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -177,6 +175,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("The placement style of biomes") private IrisGeneratorStyle skylandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("Generate caves or not.") + private boolean caves = true; + @Desc("Instead of filling objects with air, fills them with cobweb so you can see them") private boolean debugSmartBore = false; @@ -209,6 +210,9 @@ public class IrisDimension extends IrisRegistrant { @Desc("Add painted walls in post processing") private boolean postProcessingWalls = true; + @Desc("Use post processing for caves or not") + private boolean postProcessCaves = true; + @Desc("The world environment") private Environment environment = Environment.NORMAL; @@ -301,6 +305,10 @@ public class IrisDimension extends IrisRegistrant { @Desc("Overlay additional noise on top of the interoplated terrain.") private KList overlayNoise = new KList<>(); + @ArrayType(min = 1, type = IrisCaveLayer.class) + @Desc("Define cave layers") + private KList caveLayers = new KList<>(); + @ArrayType(min = 1, type = IrisCarveLayer.class) @Desc("Define carve layers") private KList carveLayers = new KList<>(); @@ -322,10 +330,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Cartographer map trade overrides") private IrisVillagerOverride patchCartographers = new IrisVillagerOverride().setDisableTrade(false); - @Desc("Register caves to generate") - @ArrayType(min = 1, type = IrisCavePlacer.class) - private KList caves = new KList<>(); - private final transient AtomicCache parallaxSize = new AtomicCache<>(); private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java index 02b1015fb..3ae2d9d39 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntitySpawn.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; @@ -82,8 +83,23 @@ public class IrisEntitySpawn implements IRare { int h = gen.getHeight(x, z, true); int hf = gen.getHeight(x, z, false); Location l = switch (getReferenceSpawner().getGroup()) { - case NORMAL, CAVE -> new Location(c.getWorld(), x, hf + 1, z); - // TODO HANDLE CAVES + case NORMAL -> new Location(c.getWorld(), x, hf + 1, z); + case CAVE -> { + IrisComplex comp = gen.getComplex(); + IrisBiome cave = comp.getCaveBiomeStream().get(x, z); + KList r = new KList<>(); + if (cave != null) { + for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) { + if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) { + continue; + } + + r.add(new Location(c.getWorld(), x, i.getFloor(), z)); + } + } + + yield r.getRandom(rng); + } case UNDERWATER, BEACH -> new Location(c.getWorld(), x, rng.i(h + 1, hf), z); }; diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java index 5c6904005..c24ea2ab8 100644 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java @@ -27,7 +27,6 @@ import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockDrops; -import com.volmit.iris.engine.object.cave.IrisCavePlacer; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -70,10 +69,6 @@ public class IrisRegion extends IrisRegistrant implements IRare { @Desc("The name of the region") private String name = "A Region"; - @Desc("Register caves to generate") - @ArrayType(min = 1, type = IrisCavePlacer.class) - private KList caves = new KList<>(); - @ArrayType(min = 1, type = IrisJigsawStructurePlacement.class) @Desc("Jigsaw structures") private KList jigsawStructures = new KList<>(); diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 409a8b14e..351882140 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -24,8 +24,7 @@ public enum MantleFlag { OBJECT, UPDATE, JIGSAW, - FEATURE, - CAVE; + FEATURE; static StateList getStateList() { return new StateList(MantleFlag.values()); From 42d3b4c3268fd6290452c10e9d6334c9387e0ba1 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Fri, 20 Aug 2021 01:34:24 -0400 Subject: [PATCH 12/39] Auto stash before revert of "Test" --- .../iris/engine/object/cave/IrisCavePlacer.java | 13 +++++++++++-- .../volmit/iris/engine/object/noise/IrisWorm.java | 2 +- .../java/com/volmit/iris/util/mantle/Mantle.java | 1 - .../com/volmit/iris/util/noise/WormIterator3.java | 14 +++++++++++--- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java index a3142e307..3f1ac227d 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCavePlacer.java @@ -25,6 +25,7 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.B; @@ -32,11 +33,13 @@ import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.Worm3; import com.volmit.iris.util.noise.WormIterator3; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import org.bukkit.block.data.BlockData; +import org.bukkit.util.BlockVector; import org.bukkit.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; @@ -56,6 +59,7 @@ public class IrisCavePlacer implements IRare { @MinNumber(1) @Required + @Desc("The cave to place") @RegistryListResource(IrisCave.class) private String cave; @@ -85,14 +89,19 @@ public class IrisCavePlacer implements IRare { WormIterator3 w = cave.getWorm().iterate3D(rng, data, x, y, z); KList points = new KList<>(); - + int itr = 0; while(w.hasNext()) { + itr++; Worm3 wx = w.next(); points.add(new Vector(wx.getX().getPosition(), wx.getY().getPosition(), wx.getZ().getPosition())); } - mantle.setSpline(points, cave.getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR); + + Iris.info(x + " " + y + " " + z + " /." + " POS: " + points.convert((i) -> "[" + i.getBlockX() + "," + i.getBlockY() + "," + i.getBlockZ() + "]").toString(", ")); + + mantle.setLine(points.convert(IrisPosition::new), cave.getWorm().getGirth().get(rng, x, z, data), true, CAVE_AIR); + // TODO decorate somehow } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java index 4ea19c752..97b862308 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisWorm.java @@ -66,7 +66,7 @@ public class IrisWorm { public NoiseProvider getAngleProvider(RNG rng, IrisData data) { - return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).noise(xx, zz) * segmentDistance.get(rng, xx, zz, data)); + return angleProviderCache.aquire(() -> (xx, zz) -> angleStyle.create(rng, data).fitDouble(-0.5, 0.5, xx, zz) * segmentDistance.get(rng, xx, zz, data)); } public WormIterator2 iterate2D(RNG rng, IrisData data, int x, int z) diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 8113ef80b..a5ad56d6b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -795,7 +795,6 @@ public class Mantle { } } - public void set(IrisPosition pos, T data) { set(pos.getX(), pos.getY(), pos.getZ(), data); diff --git a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java index 6f9204d21..dfe2b7e00 100644 --- a/src/main/java/com/volmit/iris/util/noise/WormIterator3.java +++ b/src/main/java/com/volmit/iris/util/noise/WormIterator3.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.noise; +import com.volmit.iris.Iris; import com.volmit.iris.util.function.NoiseProvider; import lombok.Builder; import lombok.Data; @@ -35,9 +36,15 @@ public class WormIterator3 { public boolean hasNext() { + if(worm == null) + { + return true; + } + double dist = maxDistance - (Math.max(Math.max(Math.abs(worm.getX().getVelocity()), Math.abs(worm.getZ().getVelocity())), Math.abs(worm.getY().getVelocity())) + 1); + return maxIterations > 0 && ((x * x) - (worm.getX().getPosition() * worm.getX().getPosition())) + ((y * y) - (worm.getY().getPosition() * worm.getY().getPosition())) @@ -46,15 +53,16 @@ public class WormIterator3 { public Worm3 next() { + maxIterations--; if(worm == null) { worm = new Worm3(x, y, z, 0, 0, 0); return worm; } - worm.getX().setVelocity(noise.noise(worm.getX().getPosition(), 0)); - worm.getY().setVelocity(noise.noise(worm.getY().getPosition(), 0)); - worm.getZ().setVelocity(noise.noise(worm.getZ().getPosition(), 0)); + worm.getX().setVelocity(worm.getX().getVelocity() + noise.noise(worm.getX().getPosition() + 10000, 0)); + worm.getY().setVelocity(worm.getY().getVelocity() + noise.noise(worm.getY().getPosition() + 1000, 0)); + worm.getZ().setVelocity(worm.getZ().getVelocity() + noise.noise(worm.getZ().getPosition() - 10000, 0)); worm.step(); return worm; From 3eb4962d7d28e327ab515c3e95bf05db9116acbd Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 00:25:27 -0400 Subject: [PATCH 13/39] f --- src/main/java/com/volmit/iris/Iris.java | 2 +- .../studio/CommandIrisStudioUpdate.java | 3 +- .../volmit/iris/core/decrees/DecStudio.java | 4 +- .../iris/core/gui/NoiseExplorerGUI.java | 3 +- .../methods/AsyncPregenMethod.java | 3 +- .../iris/core/service/PreservationSVC.java | 17 +-- .../iris/engine/framework/EngineTarget.java | 6 +- .../engine/platform/HeadlessGenerator.java | 3 +- .../com/volmit/iris/util/mantle/Mantle.java | 33 ++++- .../volmit/iris/util/parallel/MultiBurst.java | 114 +++--------------- 10 files changed, 56 insertions(+), 132 deletions(-) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index fd93d97a8..b1866351e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -27,7 +27,6 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -165,6 +164,7 @@ public class Iris extends VolmitPlugin implements Listener { HandlerList.unregisterAll((Plugin) this); postShutdown.forEach(Runnable::run); services.clear(); + MultiBurst.burst.close(); super.onDisable(); } diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index f705d75e8..dcb5d5ee1 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0])); int t = data.getObjectLoader().getPossibleKeys().length; ChronoLatch cl = new ChronoLatch(250, false); - MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst bx = MultiBurst.burst; BurstExecutor b = bx.burst(); int g = 0; for (String f : data.getObjectLoader().getPossibleKeys()) { @@ -102,7 +102,6 @@ public class CommandIrisStudioUpdate extends MortarCommand { int finalG = g; J.a(() -> { b.complete(); - bx.shutdownNow(); sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!"); }); } diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java index 7a243f2aa..00f4f1275 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java @@ -133,7 +133,7 @@ public class DecStudio implements DecreeExecutor { KList jobs = new KList<>(); KList files = new KList(); files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files); - MultiBurst burst = new MultiBurst("Cleaner", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() * 2); + MultiBurst burst = MultiBurst.burst; jobs.add(new SingleJob("Updating Workspace", () -> { if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) { @@ -237,8 +237,6 @@ public class DecStudio implements DecreeExecutor { jobs.add(q); } - jobs.add(new SingleJob("Finishing Up", burst::shutdownNow)); - new JobCollection("Cleaning", jobs).execute(sender()); } diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index fa612adcb..36a631e17 100644 --- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List static double ascale = 10; CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong())); @SuppressWarnings("CanBeFinal") - MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst gx = MultiBurst.burst; ReentrantLock l = new ReentrantLock(); BufferedImage img; int w = 0; @@ -299,7 +299,6 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { - nv.gx.shutdownLater(); Iris.instance.unregisterListener(nv); } }); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 43e9ca166..137a57595 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -41,7 +41,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } this.world = world; - burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads); + burst = MultiBurst.burst; future = new KList<>(1024); } @@ -92,7 +92,6 @@ public class AsyncPregenMethod implements PregeneratorMethod { @Override public void close() { waitForChunks(); - burst.shutdownAndAwait(); unloadAndSaveAllChunks(); } diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java index 49a7a8ad0..a6ea2ac7f 100644 --- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java +++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java @@ -31,7 +31,6 @@ import java.util.concurrent.ExecutorService; public class PreservationSVC implements IrisService { private KList threads = new KList<>(); - private KList bursts = new KList<>(); private KList services = new KList<>(); private Looper dereferencer; @@ -42,7 +41,7 @@ public class PreservationSVC implements IrisService public void register(MultiBurst burst) { - bursts.add(burst); + } public void register(ExecutorService service) @@ -94,20 +93,6 @@ public class PreservationSVC implements IrisService } } - for(MultiBurst i : bursts) - { - try - { - i.shutdownNow(); - Iris.info("Shutdown Multiburst " + i); - } - - catch(Throwable e) - { - Iris.reportError(e); - } - } - for(ExecutorService i : services) { try diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index 250b343cb..7a7c18b4a 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -36,9 +36,7 @@ public class EngineTarget { this.world = world; this.dimension = dimension; this.data = data; - this.burster = new MultiBurst("Iris Engine " + dimension.getName(), - IrisSettings.get().getConcurrency().getEngineThreadPriority(), - IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())); + this.burster = MultiBurst.burst; } public int getHeight() { @@ -46,6 +44,6 @@ public class EngineTarget { } public void close() { - burster.shutdownLater(); + } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index f3701efb2..4def637ca 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -58,7 +58,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator { public HeadlessGenerator(HeadlessWorld world) { this.world = world; - burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())); + burst = MultiBurst.burst; writer = new NBTWorld(world.getWorld().worldFolder()); engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio()); } @@ -131,7 +131,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } public void close() { - burst.shutdownAndAwait(); getEngine().close(); writer.close(); } diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index a5ad56d6b..4d120dfae 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -80,7 +80,7 @@ public class Mantle { unload = new KSet<>(); loadedRegions = new KMap<>(); lastUse = new KMap<>(); - ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2); + ioBurst = MultiBurst.burst; Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } @@ -126,6 +126,19 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + /** + * Check very quickly if a tectonic plate exists via cached or the file system + * @param x the x region coordinate + * @param z the z region coordinate + * @return true if it exists + */ + @RegionCoordinates + public boolean hasTectonicPlate(int x, int z) + { + Long k = key(x, z); + return loadedRegions.containsKey(k) || fileForRegion(dataFolder, k).exists(); + } + /** * Iterate data in a chunk * @param x the chunk x @@ -137,6 +150,11 @@ public class Mantle { */ @ChunkCoordinates public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return; + } + for (MantleFlag i : requiredFlags) { if (!hasFlag(x, z, i)) { return; @@ -155,6 +173,11 @@ public class Mantle { */ @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return false; + } + return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); } @@ -211,7 +234,12 @@ public class Mantle { throw new RuntimeException("The Mantle is closed"); } - if (y < 0) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return null; + } + + if (y < 0 || y >= worldHeight) { return null; } @@ -263,7 +291,6 @@ public class Mantle { Iris.reportError(e); } - ioBurst.shutdownNow(); Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 92a07825e..d625cbe59 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -19,13 +19,9 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.Looper; import java.util.List; import java.util.concurrent.*; @@ -33,66 +29,39 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; public class MultiBurst { - public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); + public static final MultiBurst burst = new MultiBurst(); private ExecutorService service; - private final Looper heartbeat; private final AtomicLong last; - private int tid; private final String name; - private final int tc; private final int priority; - private final int instance; - public MultiBurst(int tc) { - this("Iris", 6, tc); + public MultiBurst() { + this("Iris", Thread.MIN_PRIORITY); } - public MultiBurst(String name, int priority, int tc) { + public MultiBurst(String name, int priority) { this.name = name; this.priority = priority; - this.tc = tc; - instance = InstanceState.getInstanceId(); last = new AtomicLong(M.ms()); - heartbeat = new Looper() { - @Override - protected long loop() { - if (instance != InstanceState.getInstanceId()) { - shutdownNow(); - return -1; - } - - if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) { - service.shutdown(); - service = null; - Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources."); - } - - return 30000; - } - }; - heartbeat.setName(name + " Monitor"); - heartbeat.start(); Iris.service(PreservationSVC.class).register(this); } private synchronized ExecutorService getService() { last.set(M.ms()); if (service == null || service.isShutdown()) { - service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> { - tid++; - Thread t = new Thread(r); - t.setName(name + " " + tid); - t.setPriority(priority); - t.setUncaughtExceptionHandler((et, e) -> - { - Iris.info("Exception encountered in " + et.getName()); - e.printStackTrace(); - }); + service = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), + new ForkJoinPool.ForkJoinWorkerThreadFactory() { + int m = 0; - return t; - }); - Iris.service(PreservationSVC.class).register(service); - Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority."); + @Override + public ForkJoinWorkerThread newThread(ForkJoinPool pool) { + final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); + worker.setPriority(priority); + worker.setName(name + " " + ++m); + return worker; + } + }, + (t, e) -> e.printStackTrace(), true); } return service; @@ -146,56 +115,7 @@ public class MultiBurst { return CompletableFuture.supplyAsync(o, getService()); } - public void shutdownNow() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdownNow().forEach(Runnable::run); - } - } - - public void shutdown() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdown(); - } - } - - public void shutdownLater() { - if (service != null) { - try - { - service.submit(() -> { - J.sleep(3000); - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - }); - - heartbeat.interrupt(); - } - - catch(Throwable e) - { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - - heartbeat.interrupt(); - } - } - } - - public void shutdownAndAwait() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); + public void close() { if (service != null) { service.shutdown(); try { From 59399124fa168566b4a2113df6a8678db4486824 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 00:29:01 -0400 Subject: [PATCH 14/39] Fix mantle --- .../com/volmit/iris/util/mantle/Mantle.java | 33 ++----------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 4d120dfae..a5ad56d6b 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -80,7 +80,7 @@ public class Mantle { unload = new KSet<>(); loadedRegions = new KMap<>(); lastUse = new KMap<>(); - ioBurst = MultiBurst.burst; + ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2); Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } @@ -126,19 +126,6 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } - /** - * Check very quickly if a tectonic plate exists via cached or the file system - * @param x the x region coordinate - * @param z the z region coordinate - * @return true if it exists - */ - @RegionCoordinates - public boolean hasTectonicPlate(int x, int z) - { - Long k = key(x, z); - return loadedRegions.containsKey(k) || fileForRegion(dataFolder, k).exists(); - } - /** * Iterate data in a chunk * @param x the chunk x @@ -150,11 +137,6 @@ public class Mantle { */ @ChunkCoordinates public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { - if(!hasTectonicPlate(x >> 5, z >> 5)) - { - return; - } - for (MantleFlag i : requiredFlags) { if (!hasFlag(x, z, i)) { return; @@ -173,11 +155,6 @@ public class Mantle { */ @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { - if(!hasTectonicPlate(x >> 5, z >> 5)) - { - return false; - } - return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); } @@ -234,12 +211,7 @@ public class Mantle { throw new RuntimeException("The Mantle is closed"); } - if(!hasTectonicPlate(x >> 5, z >> 5)) - { - return null; - } - - if (y < 0 || y >= worldHeight) { + if (y < 0) { return null; } @@ -291,6 +263,7 @@ public class Mantle { Iris.reportError(e); } + ioBurst.shutdownNow(); Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } From 4b991ab67af6cd09e1e99ab22d17affdee666e8a Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 00:29:05 -0400 Subject: [PATCH 15/39] f --- src/main/java/com/volmit/iris/Iris.java | 2 +- .../studio/CommandIrisStudioUpdate.java | 3 +- .../volmit/iris/core/decrees/DecStudio.java | 4 +- .../iris/core/gui/NoiseExplorerGUI.java | 3 +- .../methods/AsyncPregenMethod.java | 3 +- .../iris/core/service/PreservationSVC.java | 17 ++- .../iris/engine/framework/EngineTarget.java | 6 +- .../engine/platform/HeadlessGenerator.java | 3 +- .../volmit/iris/util/parallel/MultiBurst.java | 114 +++++++++++++++--- 9 files changed, 129 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index b1866351e..fd93d97a8 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -27,6 +27,7 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -164,7 +165,6 @@ public class Iris extends VolmitPlugin implements Listener { HandlerList.unregisterAll((Plugin) this); postShutdown.forEach(Runnable::run); services.clear(); - MultiBurst.burst.close(); super.onDisable(); } diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index dcb5d5ee1..f705d75e8 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0])); int t = data.getObjectLoader().getPossibleKeys().length; ChronoLatch cl = new ChronoLatch(250, false); - MultiBurst bx = MultiBurst.burst; + MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); BurstExecutor b = bx.burst(); int g = 0; for (String f : data.getObjectLoader().getPossibleKeys()) { @@ -102,6 +102,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { int finalG = g; J.a(() -> { b.complete(); + bx.shutdownNow(); sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!"); }); } diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java index 00f4f1275..7a243f2aa 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java @@ -133,7 +133,7 @@ public class DecStudio implements DecreeExecutor { KList jobs = new KList<>(); KList files = new KList(); files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files); - MultiBurst burst = MultiBurst.burst; + MultiBurst burst = new MultiBurst("Cleaner", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() * 2); jobs.add(new SingleJob("Updating Workspace", () -> { if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) { @@ -237,6 +237,8 @@ public class DecStudio implements DecreeExecutor { jobs.add(q); } + jobs.add(new SingleJob("Finishing Up", burst::shutdownNow)); + new JobCollection("Cleaning", jobs).execute(sender()); } diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index 36a631e17..fa612adcb 100644 --- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List static double ascale = 10; CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong())); @SuppressWarnings("CanBeFinal") - MultiBurst gx = MultiBurst.burst; + MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors()); ReentrantLock l = new ReentrantLock(); BufferedImage img; int w = 0; @@ -299,6 +299,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { + nv.gx.shutdownLater(); Iris.instance.unregisterListener(nv); } }); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 137a57595..43e9ca166 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -41,7 +41,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } this.world = world; - burst = MultiBurst.burst; + burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads); future = new KList<>(1024); } @@ -92,6 +92,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { @Override public void close() { waitForChunks(); + burst.shutdownAndAwait(); unloadAndSaveAllChunks(); } diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java index a6ea2ac7f..49a7a8ad0 100644 --- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java +++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java @@ -31,6 +31,7 @@ import java.util.concurrent.ExecutorService; public class PreservationSVC implements IrisService { private KList threads = new KList<>(); + private KList bursts = new KList<>(); private KList services = new KList<>(); private Looper dereferencer; @@ -41,7 +42,7 @@ public class PreservationSVC implements IrisService public void register(MultiBurst burst) { - + bursts.add(burst); } public void register(ExecutorService service) @@ -93,6 +94,20 @@ public class PreservationSVC implements IrisService } } + for(MultiBurst i : bursts) + { + try + { + i.shutdownNow(); + Iris.info("Shutdown Multiburst " + i); + } + + catch(Throwable e) + { + Iris.reportError(e); + } + } + for(ExecutorService i : services) { try diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index 7a7c18b4a..250b343cb 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -36,7 +36,9 @@ public class EngineTarget { this.world = world; this.dimension = dimension; this.data = data; - this.burster = MultiBurst.burst; + this.burster = new MultiBurst("Iris Engine " + dimension.getName(), + IrisSettings.get().getConcurrency().getEngineThreadPriority(), + IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())); } public int getHeight() { @@ -44,6 +46,6 @@ public class EngineTarget { } public void close() { - + burster.shutdownLater(); } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index 4def637ca..f3701efb2 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -58,7 +58,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator { public HeadlessGenerator(HeadlessWorld world) { this.world = world; - burst = MultiBurst.burst; + burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())); writer = new NBTWorld(world.getWorld().worldFolder()); engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio()); } @@ -131,6 +131,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } public void close() { + burst.shutdownAndAwait(); getEngine().close(); writer.close(); } diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index d625cbe59..92a07825e 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -19,9 +19,13 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.math.M; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.Looper; import java.util.List; import java.util.concurrent.*; @@ -29,39 +33,66 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; public class MultiBurst { - public static final MultiBurst burst = new MultiBurst(); + public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); private ExecutorService service; + private final Looper heartbeat; private final AtomicLong last; + private int tid; private final String name; + private final int tc; private final int priority; + private final int instance; - public MultiBurst() { - this("Iris", Thread.MIN_PRIORITY); + public MultiBurst(int tc) { + this("Iris", 6, tc); } - public MultiBurst(String name, int priority) { + public MultiBurst(String name, int priority, int tc) { this.name = name; this.priority = priority; + this.tc = tc; + instance = InstanceState.getInstanceId(); last = new AtomicLong(M.ms()); + heartbeat = new Looper() { + @Override + protected long loop() { + if (instance != InstanceState.getInstanceId()) { + shutdownNow(); + return -1; + } + + if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) { + service.shutdown(); + service = null; + Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources."); + } + + return 30000; + } + }; + heartbeat.setName(name + " Monitor"); + heartbeat.start(); Iris.service(PreservationSVC.class).register(this); } private synchronized ExecutorService getService() { last.set(M.ms()); if (service == null || service.isShutdown()) { - service = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), - new ForkJoinPool.ForkJoinWorkerThreadFactory() { - int m = 0; + service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> { + tid++; + Thread t = new Thread(r); + t.setName(name + " " + tid); + t.setPriority(priority); + t.setUncaughtExceptionHandler((et, e) -> + { + Iris.info("Exception encountered in " + et.getName()); + e.printStackTrace(); + }); - @Override - public ForkJoinWorkerThread newThread(ForkJoinPool pool) { - final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); - worker.setPriority(priority); - worker.setName(name + " " + ++m); - return worker; - } - }, - (t, e) -> e.printStackTrace(), true); + return t; + }); + Iris.service(PreservationSVC.class).register(service); + Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority."); } return service; @@ -115,7 +146,56 @@ public class MultiBurst { return CompletableFuture.supplyAsync(o, getService()); } - public void close() { + public void shutdownNow() { + Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); + heartbeat.interrupt(); + + if (service != null) { + service.shutdownNow().forEach(Runnable::run); + } + } + + public void shutdown() { + Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); + heartbeat.interrupt(); + + if (service != null) { + service.shutdown(); + } + } + + public void shutdownLater() { + if (service != null) { + try + { + service.submit(() -> { + J.sleep(3000); + Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); + + if (service != null) { + service.shutdown(); + } + }); + + heartbeat.interrupt(); + } + + catch(Throwable e) + { + Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); + + if (service != null) { + service.shutdown(); + } + + heartbeat.interrupt(); + } + } + } + + public void shutdownAndAwait() { + Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); + heartbeat.interrupt(); if (service != null) { service.shutdown(); try { From 72b4c9c6ab5c813ac6467d12bc71a4667fc711c6 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 00:29:01 -0400 Subject: [PATCH 16/39] Revert "Fix mantle " This reverts commit 59399124fa168566b4a2113df6a8678db4486824. --- .../com/volmit/iris/util/mantle/Mantle.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index a5ad56d6b..4d120dfae 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -80,7 +80,7 @@ public class Mantle { unload = new KSet<>(); loadedRegions = new KMap<>(); lastUse = new KMap<>(); - ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2); + ioBurst = MultiBurst.burst; Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } @@ -126,6 +126,19 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + /** + * Check very quickly if a tectonic plate exists via cached or the file system + * @param x the x region coordinate + * @param z the z region coordinate + * @return true if it exists + */ + @RegionCoordinates + public boolean hasTectonicPlate(int x, int z) + { + Long k = key(x, z); + return loadedRegions.containsKey(k) || fileForRegion(dataFolder, k).exists(); + } + /** * Iterate data in a chunk * @param x the chunk x @@ -137,6 +150,11 @@ public class Mantle { */ @ChunkCoordinates public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return; + } + for (MantleFlag i : requiredFlags) { if (!hasFlag(x, z, i)) { return; @@ -155,6 +173,11 @@ public class Mantle { */ @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return false; + } + return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); } @@ -211,7 +234,12 @@ public class Mantle { throw new RuntimeException("The Mantle is closed"); } - if (y < 0) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return null; + } + + if (y < 0 || y >= worldHeight) { return null; } @@ -263,7 +291,6 @@ public class Mantle { Iris.reportError(e); } - ioBurst.shutdownNow(); Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } From d686d07d53f3dc69def5a3df40fdc6f95d05c878 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 02:42:22 -0400 Subject: [PATCH 17/39] Iris but forkjoin --- src/main/java/com/volmit/iris/Iris.java | 12 +- .../studio/CommandIrisStudioUpdate.java | 3 +- .../volmit/iris/core/decrees/DecStudio.java | 7 +- .../iris/core/gui/NoiseExplorerGUI.java | 3 +- .../methods/AsyncPregenMethod.java | 8 +- .../iris/core/service/PreservationSVC.java | 17 +-- .../com/volmit/iris/engine/IrisEngine.java | 41 ++++-- .../volmit/iris/engine/IrisEngineMantle.java | 28 +++- .../engine/actuator/IrisBiomeActuator.java | 1 - .../engine/actuator/IrisDecorantActuator.java | 1 - .../actuator/IrisTerrainNormalActuator.java | 1 - .../framework/EngineAssignedActuator.java | 2 + .../framework/EngineAssignedComponent.java | 2 + .../framework/EngineAssignedModifier.java | 2 + .../iris/engine/framework/EngineTarget.java | 6 +- .../iris/engine/mantle/EngineMantle.java | 23 +--- .../engine/modifier/IrisDepositModifier.java | 2 +- .../engine/modifier/IrisPostModifier.java | 1 - .../engine/platform/BukkitChunkGenerator.java | 5 +- .../engine/platform/HeadlessGenerator.java | 3 +- .../com/volmit/iris/util/mantle/Mantle.java | 8 +- .../iris/util/parallel/BurstExecutor.java | 59 ++------- .../volmit/iris/util/parallel/MultiBurst.java | 123 ++++-------------- 23 files changed, 125 insertions(+), 233 deletions(-) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index fd93d97a8..24b44b73e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -27,7 +27,6 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -49,6 +48,7 @@ import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.io.JarScanner; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.*; import com.volmit.iris.util.reflect.ShadeFix; @@ -165,6 +165,7 @@ public class Iris extends VolmitPlugin implements Listener { HandlerList.unregisterAll((Plugin) this); postShutdown.forEach(Runnable::run); services.clear(); + MultiBurst.burst.close(); super.onDisable(); } @@ -604,14 +605,7 @@ public class Iris extends VolmitPlugin implements Listener { } public static void verbose(String string) { - try { - if (IrisSettings.get().getGeneral().isVerbose()) { - msg(C.GRAY + string); - } - } catch (Throwable e) { - msg(C.GRAY + string); - Iris.reportError(e); - } + debug(string); } public static void success(String string) { diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index f705d75e8..dcb5d5ee1 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0])); int t = data.getObjectLoader().getPossibleKeys().length; ChronoLatch cl = new ChronoLatch(250, false); - MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst bx = MultiBurst.burst; BurstExecutor b = bx.burst(); int g = 0; for (String f : data.getObjectLoader().getPossibleKeys()) { @@ -102,7 +102,6 @@ public class CommandIrisStudioUpdate extends MortarCommand { int finalG = g; J.a(() -> { b.complete(); - bx.shutdownNow(); sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!"); }); } diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java index 7a243f2aa..6c4cbe873 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java @@ -78,6 +78,7 @@ import java.io.File; import java.io.IOException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.function.Supplier; @Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true) @@ -133,7 +134,7 @@ public class DecStudio implements DecreeExecutor { KList jobs = new KList<>(); KList files = new KList(); files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files); - MultiBurst burst = new MultiBurst("Cleaner", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() * 2); + MultiBurst burst = MultiBurst.burst; jobs.add(new SingleJob("Updating Workspace", () -> { if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) { @@ -208,7 +209,7 @@ public class DecStudio implements DecreeExecutor { IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())); for (String f : data.getObjectLoader().getPossibleKeys()) { - CompletableFuture gg = burst.complete(() -> { + Future gg = burst.complete(() -> { File ff = data.getObjectLoader().findFile(f); IrisObject oo = new IrisObject(0, 0, 0); try { @@ -237,8 +238,6 @@ public class DecStudio implements DecreeExecutor { jobs.add(q); } - jobs.add(new SingleJob("Finishing Up", burst::shutdownNow)); - new JobCollection("Cleaning", jobs).execute(sender()); } diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index fa612adcb..36a631e17 100644 --- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List static double ascale = 10; CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong())); @SuppressWarnings("CanBeFinal") - MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst gx = MultiBurst.burst; ReentrantLock l = new ReentrantLock(); BufferedImage img; int w = 0; @@ -299,7 +299,6 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { - nv.gx.shutdownLater(); Iris.instance.unregisterListener(nv); } }); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 43e9ca166..64a1fbe53 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -29,11 +29,12 @@ import org.bukkit.Chunk; import org.bukkit.World; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; public class AsyncPregenMethod implements PregeneratorMethod { private final World world; private final MultiBurst burst; - private final KList> future; + private final KList> future; public AsyncPregenMethod(World world, int threads) { if (!PaperLib.isPaper()) { @@ -41,7 +42,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } this.world = world; - burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads); + burst = MultiBurst.burst; future = new KList<>(1024); } @@ -69,7 +70,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } private void waitForChunks() { - for (CompletableFuture i : future.copy()) { + for (Future i : future.copy()) { try { i.get(); future.remove(i); @@ -92,7 +93,6 @@ public class AsyncPregenMethod implements PregeneratorMethod { @Override public void close() { waitForChunks(); - burst.shutdownAndAwait(); unloadAndSaveAllChunks(); } diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java index 49a7a8ad0..a6ea2ac7f 100644 --- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java +++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java @@ -31,7 +31,6 @@ import java.util.concurrent.ExecutorService; public class PreservationSVC implements IrisService { private KList threads = new KList<>(); - private KList bursts = new KList<>(); private KList services = new KList<>(); private Looper dereferencer; @@ -42,7 +41,7 @@ public class PreservationSVC implements IrisService public void register(MultiBurst burst) { - bursts.add(burst); + } public void register(ExecutorService service) @@ -94,20 +93,6 @@ public class PreservationSVC implements IrisService } } - for(MultiBurst i : bursts) - { - try - { - i.shutdownNow(); - Iris.info("Shutdown Multiburst " + i); - } - - catch(Throwable e) - { - Iris.reportError(e); - } - } - for(ExecutorService i : services) { try diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index cb973fc0c..225c3a795 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -132,6 +132,7 @@ public class IrisEngine extends BlockPopulator implements Engine { closed = false; art = J.ar(this::tickRandomPlayer, 0); setupEngine(); + Iris.debug("Engine Initialized " + getCacheID()); } private void tickRandomPlayer() { @@ -158,20 +159,32 @@ public class IrisEngine extends BlockPopulator implements Engine { private void setupEngine() { - cacheId = RNG.r.nextInt(); - worldManager = new IrisWorldManager(this); - complex = new IrisComplex(this); - execution = new IrisExecutionEnvironment(this); - terrainNormalActuator = new IrisTerrainNormalActuator(this); - terrainIslandActuator = new IrisTerrainIslandActuator(this); - decorantActuator = new IrisDecorantActuator(this); - biomeActuator = new IrisBiomeActuator(this); - depositModifier = new IrisDepositModifier(this); - ravineModifier = new IrisRavineModifier(this); - caveModifier = new IrisCaveModifier(this); - postModifier = new IrisPostModifier(this); - effects = new IrisEngineEffects(this); - J.a(this::computeBiomeMaxes); + try + { + Iris.debug("Setup Engine " + getCacheID()); + cacheId = RNG.r.nextInt(); + worldManager = new IrisWorldManager(this); + complex = new IrisComplex(this); + execution = new IrisExecutionEnvironment(this); + terrainNormalActuator = new IrisTerrainNormalActuator(this); + terrainIslandActuator = new IrisTerrainIslandActuator(this); + decorantActuator = new IrisDecorantActuator(this); + biomeActuator = new IrisBiomeActuator(this); + depositModifier = new IrisDepositModifier(this); + ravineModifier = new IrisRavineModifier(this); + caveModifier = new IrisCaveModifier(this); + postModifier = new IrisPostModifier(this); + effects = new IrisEngineEffects(this); + J.a(this::computeBiomeMaxes); + } + + catch(Throwable e) + { + Iris.error("FAILED TO SETUP ENGINE!"); + e.printStackTrace(); + } + + Iris.debug("Engine Setup Complete " + getCacheID()); } @Override diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index 132056578..e3296fc1a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine; +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; @@ -27,6 +28,7 @@ import com.volmit.iris.engine.mantle.components.MantleJigsawComponent; import com.volmit.iris.engine.mantle.components.MantleObjectComponent; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; import com.volmit.iris.engine.object.objects.IrisObject; @@ -36,9 +38,15 @@ import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.stream.ProceduralStream; +import com.volmit.iris.util.stream.interpolation.Interpolated; +import com.volmit.iris.util.stream.utility.CachedStream2D; import lombok.Data; import org.bukkit.util.BlockVector; @@ -46,6 +54,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; @Data @@ -53,7 +62,9 @@ public class IrisEngineMantle implements EngineMantle { private final Engine engine; private final Mantle mantle; private final KList components; - private final CompletableFuture radius; + private final Future radius; + private ProceduralStream> featureChunkStream; + private ProceduralStream> featureStream; public IrisEngineMantle(Engine engine) { this.engine = engine; @@ -63,6 +74,21 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); + featureChunkStream = ProceduralStream.of((x, z) + -> EngineMantle.super.getFeaturesInChunk(x.intValue(), z.intValue()), + Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(2048); + featureStream = ProceduralStream.of(EngineMantle.super::forEachFeature, + Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(8192); + } + + @ChunkCoordinates + public KList getFeaturesInChunk(int x, int z) { + return featureChunkStream.get(x, z); + } + + @BlockCoordinates + public KList forEachFeature(double x, double z) { + return featureStream.get(x, z); } @Override diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 45b8fd31c..226ebab98 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -69,7 +69,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator { public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); BurstExecutor burst = burst().burst(); - burst.setMulticore(multicore); for (int xf = 0; xf < h.getWidth(); xf++) { int finalXf = xf; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 744f30048..e2a8b9e1c 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -91,7 +91,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator { PrecisionStopwatch p = PrecisionStopwatch.start(); BurstExecutor burst = burst().burst(); - burst.setMulticore(multicore); for (int i = 0; i < output.getWidth(); i++) { int finalI = i; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index c99951982..91ec3d0f7 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -56,7 +56,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator PrecisionStopwatch p = PrecisionStopwatch.start(); BurstExecutor e = getEngine().burst().burst(h.getWidth()); - e.setMulticore(multicore); for (int xf = 0; xf < h.getWidth(); xf++) { int finalXf = xf; e.queue(() -> terrainSliver(x, z, finalXf, h)); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java index 77eae4f29..2698a694e 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.framework; +import com.volmit.iris.Iris; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.hunk.Hunk; @@ -31,6 +32,7 @@ public abstract class EngineAssignedActuator extends EngineAssignedComponent @BlockCoordinates @Override public void actuate(int x, int z, Hunk output, boolean multicore) { + Iris.debug("Engine Actuator[" + getName() + "] " + x + " " + z); onActuate(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java index f00cdaca1..ca1f2f9d8 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedComponent.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.framework; +import com.volmit.iris.Iris; import com.volmit.iris.util.math.RollingSequence; import lombok.Data; @@ -28,6 +29,7 @@ public class EngineAssignedComponent implements EngineComponent { private final String name; public EngineAssignedComponent(Engine engine, String name) { + Iris.debug("Engine: " + engine.getCacheID() + " Starting " + name); this.engine = engine; this.metrics = new RollingSequence(16); this.name = name; diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java index 6bcbd2267..8e5bb8fb6 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.framework; +import com.volmit.iris.Iris; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.hunk.Hunk; @@ -32,6 +33,7 @@ public abstract class EngineAssignedModifier extends EngineAssignedComponent @BlockCoordinates @Override public void modify(int x, int z, Hunk output, boolean multicore) { + Iris.debug("Engine Modifier[" + getName() + "] " + x + " " + z); onModify(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index 250b343cb..7a7c18b4a 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -36,9 +36,7 @@ public class EngineTarget { this.world = world; this.dimension = dimension; this.data = data; - this.burster = new MultiBurst("Iris Engine " + dimension.getName(), - IrisSettings.get().getConcurrency().getEngineThreadPriority(), - IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())); + this.burster = MultiBurst.burst; } public int getHeight() { @@ -46,6 +44,6 @@ public class EngineTarget { } public void close() { - burster.shutdownLater(); + } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 3046f8d3c..87c905692 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -36,16 +36,11 @@ import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Chunk; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.*; import java.util.function.Consumer; // TODO: MOVE PLACER OUT OF MATTER INTO ITS OWN THING @@ -56,7 +51,7 @@ public interface EngineMantle extends IObjectPlacer { Engine getEngine(); - CompletableFuture getRadius(); + Future getRadius(); KList getComponents(); @@ -189,7 +184,6 @@ public interface EngineMantle extends IObjectPlacer { return; } - PrecisionStopwatch p = PrecisionStopwatch.start(); KList post = new KList<>(); Consumer c = (i) -> { synchronized (post) @@ -199,7 +193,6 @@ public interface EngineMantle extends IObjectPlacer { }; int s = getRealRadius(); BurstExecutor burst = burst().burst(); - burst.setMulticore(multicore); for (int i = -s; i <= s; i++) { int xx = i + x; @@ -217,16 +210,7 @@ public interface EngineMantle extends IObjectPlacer { { KList px = post.copy(); post.clear(); - - if(multicore) - { - burst().burst(px); - } - - else - { - burst().sync(px); - } + burst().burst(px); } } @@ -240,6 +224,7 @@ public interface EngineMantle extends IObjectPlacer { return; } + Iris.debug("Engine Matter Insert " + x + " " + z); getMantle().iterateChunk(x, z, t, blocks::set); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index c3402d5d6..ce8c8bc30 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -55,7 +55,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7); IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7); BurstExecutor burst = burst().burst(); - burst.setMulticore(multicore); + for (IrisDepositGenerator k : getDimension().getDeposits()) { burst.queue(() -> generate(k, terrain, ro, x, z, false)); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index fee01f68a..d5daa6b2a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -65,7 +65,6 @@ public class IrisPostModifier extends EngineAssignedModifier { AtomicInteger i = new AtomicInteger(); AtomicInteger j = new AtomicInteger(); BurstExecutor burst = burst().burst(); - burst.setMulticore(multicore); Hunk sync = output.synchronize(); for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) { burst.queue(() -> { diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 907dd6572..f0e105c87 100644 --- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -177,6 +177,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { + Iris.debug("Generate Request " + world.getName() + " at: " + x + ", " + z); try { if(lastSeed != world.getSeed()) { @@ -187,12 +188,14 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun Iris.success("Updated Engine seed to " + lastSeed); } + Iris.debug("Generate Request [LOCKING] at: " + x + ", " + z); loadLock.acquire(); - PrecisionStopwatch ps = PrecisionStopwatch.start(); + Iris.debug("Generate Request [LOCKED] at: " + x + ", " + z); TerrainChunk tc = TerrainChunk.create(world, biome); Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); this.world.bind(world); + Iris.debug("Generate Request [ENGINE] at: " + x + ", " + z); getEngine().generate(x * 16, z * 16, blocks, biomes, true); ChunkData c = tc.getRaw(); Iris.debug("Generated " + x + " " + z); diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index f3701efb2..4def637ca 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -58,7 +58,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator { public HeadlessGenerator(HeadlessWorld world) { this.world = world; - burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())); + burst = MultiBurst.burst; writer = new NBTWorld(world.getWorld().worldFolder()); engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio()); } @@ -131,7 +131,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } public void close() { - burst.shutdownAndAwait(); getEngine().close(); writer.close(); } diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 4d120dfae..3265aaef7 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -46,6 +46,7 @@ import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -386,7 +387,7 @@ public class Mantle { * @return the future of a tectonic plate. */ @RegionCoordinates - private CompletableFuture getSafe(int x, int z) { + private Future getSafe(int x, int z) { Long k = key(x, z); TectonicPlate p = loadedRegions.get(k); @@ -449,7 +450,10 @@ public class Mantle { public static File fileForRegion(File folder, Long key) { String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString(); File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp"); - f.getParentFile().mkdirs(); + if(!f.getParentFile().exists()) + { + f.getParentFile().mkdirs(); + } return f; } diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index ef6935a97..bf2aa0fb9 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -28,45 +28,27 @@ import java.util.concurrent.*; @SuppressWarnings("ALL") public class BurstExecutor { private final ExecutorService executor; - private final KList> futures; - @Setter - private boolean multicore = true; + private final KList> futures; public BurstExecutor(ExecutorService executor, int burstSizeEstimate) { this.executor = executor; - futures = new KList>(burstSizeEstimate); + futures = new KList>(burstSizeEstimate); } @SuppressWarnings("UnusedReturnValue") - public CompletableFuture queue(Runnable r) { - if(!multicore) - { - r.run(); - return null; - } - + public Future queue(Runnable r) { synchronized (futures) { - CompletableFuture c = CompletableFuture.runAsync(r, executor); + + Future c = executor.submit(r); futures.add(c); return c; } } public BurstExecutor queue(List r) { - if(!multicore) - { - for(Runnable i : r) - { - i.run(); - } - - return this; - } - synchronized (futures) { for (Runnable i : new KList<>(r)) { - CompletableFuture c = CompletableFuture.runAsync(i, executor); - futures.add(c); + queue(i); } } @@ -74,20 +56,9 @@ public class BurstExecutor { } public BurstExecutor queue(Runnable[] r) { - if(!multicore) - { - for(Runnable i : r) - { - i.run(); - } - - return this; - } - synchronized (futures) { for (Runnable i : r) { - CompletableFuture c = CompletableFuture.runAsync(i, executor); - futures.add(c); + queue(i); } } @@ -95,18 +66,17 @@ public class BurstExecutor { } public void complete() { - if(!multicore) - { - return; - } - synchronized (futures) { if (futures.isEmpty()) { return; } try { - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(); + for(Future i : futures) + { + i.get(); + } + futures.clear(); } catch (InterruptedException | ExecutionException e) { Iris.reportError(e); @@ -115,11 +85,6 @@ public class BurstExecutor { } public boolean complete(long maxDur) { - if(!multicore) - { - return true; - } - synchronized (futures) { if (futures.isEmpty()) { return true; diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 92a07825e..3ea793079 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -19,13 +19,10 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.Looper; +import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.concurrent.*; @@ -33,66 +30,39 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; public class MultiBurst { - public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); + public static final MultiBurst burst = new MultiBurst(); private ExecutorService service; - private final Looper heartbeat; private final AtomicLong last; - private int tid; private final String name; - private final int tc; private final int priority; - private final int instance; - public MultiBurst(int tc) { - this("Iris", 6, tc); + public MultiBurst() { + this("Iris", Thread.MIN_PRIORITY); } - public MultiBurst(String name, int priority, int tc) { + public MultiBurst(String name, int priority) { this.name = name; this.priority = priority; - this.tc = tc; - instance = InstanceState.getInstanceId(); last = new AtomicLong(M.ms()); - heartbeat = new Looper() { - @Override - protected long loop() { - if (instance != InstanceState.getInstanceId()) { - shutdownNow(); - return -1; - } - - if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) { - service.shutdown(); - service = null; - Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources."); - } - - return 30000; - } - }; - heartbeat.setName(name + " Monitor"); - heartbeat.start(); Iris.service(PreservationSVC.class).register(this); } private synchronized ExecutorService getService() { last.set(M.ms()); if (service == null || service.isShutdown()) { - service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> { - tid++; - Thread t = new Thread(r); - t.setName(name + " " + tid); - t.setPriority(priority); - t.setUncaughtExceptionHandler((et, e) -> - { - Iris.info("Exception encountered in " + et.getName()); - e.printStackTrace(); - }); + service = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), + new ForkJoinPool.ForkJoinWorkerThreadFactory() { + int m = 0; - return t; - }); - Iris.service(PreservationSVC.class).register(service); - Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority."); + @Override + public ForkJoinWorkerThread newThread(ForkJoinPool pool) { + final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); + worker.setPriority(priority); + worker.setName(name + " " + ++m); + return worker; + } + }, + (t, e) -> e.printStackTrace(), true); } return service; @@ -138,64 +108,15 @@ public class MultiBurst { return getService().submit(o); } - public CompletableFuture complete(Runnable o) { - return CompletableFuture.runAsync(o, getService()); + public Future complete(Runnable o) { + return getService().submit(o); } - public CompletableFuture completeValue(Supplier o) { - return CompletableFuture.supplyAsync(o, getService()); + public Future completeValue(Callable o) { + return getService().submit(o); } - public void shutdownNow() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdownNow().forEach(Runnable::run); - } - } - - public void shutdown() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdown(); - } - } - - public void shutdownLater() { - if (service != null) { - try - { - service.submit(() -> { - J.sleep(3000); - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - }); - - heartbeat.interrupt(); - } - - catch(Throwable e) - { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - - heartbeat.interrupt(); - } - } - } - - public void shutdownAndAwait() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); + public void close() { if (service != null) { service.shutdown(); try { From 71955b777bc43e9ce97b3149c38dccb7f06ec66f Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 02:52:00 -0400 Subject: [PATCH 18/39] Unreg decree for now --- src/main/java/com/volmit/iris/core/service/CommandSVC.java | 2 +- src/main/resources/plugin.yml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/service/CommandSVC.java b/src/main/java/com/volmit/iris/core/service/CommandSVC.java index 13c636d03..6adaeb2b7 100644 --- a/src/main/java/com/volmit/iris/core/service/CommandSVC.java +++ b/src/main/java/com/volmit/iris/core/service/CommandSVC.java @@ -29,7 +29,7 @@ import com.volmit.iris.util.plugin.IrisService; public class CommandSVC implements IrisService, DecreeSystem { @Override public void onEnable() { - Iris.instance.getCommand("irisd").setExecutor(this); + // TODO Iris.instance.getCommand("irisd").setExecutor(this); } @Override diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 641130bc2..59767aa97 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -17,7 +17,5 @@ libraries: commands: iris: aliases: [ ir, irs ] - irisd: - aliases: [ ird, irsd ] api-version: ${apiversion} hotload-dependencies: false \ No newline at end of file From e752a48343c8963bc9e8b615367b61710b076e06 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 02:52:11 -0400 Subject: [PATCH 19/39] Drop decree from yml for now --- out/production/resources/plugin.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/out/production/resources/plugin.yml b/out/production/resources/plugin.yml index 641130bc2..59767aa97 100644 --- a/out/production/resources/plugin.yml +++ b/out/production/resources/plugin.yml @@ -17,7 +17,5 @@ libraries: commands: iris: aliases: [ ir, irs ] - irisd: - aliases: [ ird, irsd ] api-version: ${apiversion} hotload-dependencies: false \ No newline at end of file From d3998dd03bf50716f0d1e9f51ebe211962d1d74e Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 05:56:15 -0400 Subject: [PATCH 20/39] Config tweaks --- src/main/java/com/volmit/iris/Iris.java | 3 +- .../com/volmit/iris/core/IrisSettings.java | 67 ++----------------- .../methods/HybridPregenMethod.java | 2 +- 3 files changed, 9 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 24b44b73e..7bd1f59ab 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -18,6 +18,7 @@ package com.volmit.iris; +import com.google.gson.Gson; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.command.CommandIris; import com.volmit.iris.core.command.PermissionIris; @@ -677,7 +678,7 @@ public class Iris extends VolmitPlugin implements Listener { } public boolean isMCA() { - return !IrisSettings.get().getGenerator().isDisableMCA(); + return IrisSettings.get().getGenerator().isHeadlessPregeneration(); } public static void reportErrorChunk(int x, int z, Throwable e, String extra) { diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java index 7c72ea270..b69ec5b6c 100644 --- a/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -101,7 +101,6 @@ public class IrisSettings { public static class IrisSettingsGeneral { public boolean commandSounds = true; public boolean debug = false; - public boolean verbose = false; public boolean ignoreWorldEdit = false; public boolean disableNMS = false; public boolean keepProductionOnReload = false; @@ -115,7 +114,6 @@ public class IrisSettings { @Data public static class IrisSettingsGUI { - public boolean useServerLaunchedGuis = true; public boolean maximumPregenGuiFPS = false; public boolean localPregenGui = true; @@ -124,10 +122,8 @@ public class IrisSettings { @Data public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; - public boolean disableMCA = false; + public boolean headlessPregeneration = false; public boolean systemEffects = true; - public boolean systemEntitySpawnOverrides = true; - public boolean systemEntityInitialSpawns = true; public int maxBiomeChildDepth = 4; public boolean preventLeafDecay = true; } @@ -162,65 +158,14 @@ public class IrisSettings { try { String ss = IO.readAll(s); settings = new Gson().fromJson(ss, IrisSettings.class); - - J.a(() -> - { - try { - JSONObject j = new JSONObject(ss); - boolean u = false; - for (String i : def.keySet()) { - if (!j.has(i)) { - u = true; - j.put(i, def.get(i)); - Iris.warn("Adding new config key: " + i); - } - } - - for (String i : new KSet<>(j.keySet())) { - if (!def.has(i)) { - u = true; - j.remove(i); - Iris.warn("Removing unused config key: " + i); - } - } - - if (u) { - try { - IO.writeAll(s, j.toString(4)); - Iris.info("Updated Configuration Files"); - } catch (Throwable e) { - e.printStackTrace(); - Iris.reportError(e); - } - } - } catch (Throwable ee) { - Iris.reportError(ee); - Iris.error("Configuration Error in settings.json! " + ee.getClass().getSimpleName() + ": " + ee.getMessage()); - Iris.warn("Attempting to fix configuration while retaining valid in-memory settings..."); - - try { - IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4)); - Iris.info("Configuration Fixed!"); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error("ERROR! CONFIGURATION IMPOSSIBLE TO READ! Using an unmodifiable configuration from memory. Please delete the settings.json at some point to try to restore configurability!"); - } - } - }); + try { + IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4)); + } catch (IOException e) { + e.printStackTrace(); + } } catch (Throwable ee) { Iris.reportError(ee); Iris.error("Configuration Error in settings.json! " + ee.getClass().getSimpleName() + ": " + ee.getMessage()); - Iris.warn("Attempting to fix configuration while retaining valid in-memory settings..."); - - try { - IO.writeAll(s, new JSONObject(new Gson().toJson(settings)).toString(4)); - Iris.info("Configuration Fixed!"); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error("ERROR! CONFIGURATION IMPOSSIBLE TO READ! Using an unmodifiable configuration from memory. Please delete the settings.json at some point to try to restore configurability!"); - } } } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java index 1f8b06397..f6e5a6f04 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/HybridPregenMethod.java @@ -42,7 +42,7 @@ public class HybridPregenMethod implements PregeneratorMethod { } private boolean supportsHeadless(World world) { - return IrisToolbelt.access(world) != null && !IrisSettings.get().getGenerator().isDisableMCA(); + return IrisToolbelt.access(world) != null && IrisSettings.get().getGenerator().isHeadlessPregeneration(); } @Override From 203a42c0438f35fb39c278d7e2537c000a9c4a94 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 06:21:15 -0400 Subject: [PATCH 21/39] Engine fixes --- .../java/com/volmit/iris/engine/IrisEngineMantle.java | 8 ++++---- .../iris/engine/framework/EngineAssignedActuator.java | 1 - .../iris/engine/framework/EngineAssignedModifier.java | 1 - .../java/com/volmit/iris/engine/mantle/EngineMantle.java | 3 +-- .../volmit/iris/engine/platform/BukkitChunkGenerator.java | 4 ---- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index e3296fc1a..b19098805 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -20,6 +20,7 @@ package com.volmit.iris.engine; import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.MantleComponent; @@ -53,8 +54,6 @@ import org.bukkit.util.BlockVector; import java.io.File; import java.io.IOException; import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; @Data @@ -62,14 +61,15 @@ public class IrisEngineMantle implements EngineMantle { private final Engine engine; private final Mantle mantle; private final KList components; - private final Future radius; + private final int radius; + private final AtomicCache radCache = new AtomicCache<>(); private ProceduralStream> featureChunkStream; private ProceduralStream> featureStream; public IrisEngineMantle(Engine engine) { this.engine = engine; this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle"), engine.getTarget().getHeight()); - radius = burst().completeValue(this::computeParallaxSize); + radius = radCache.aquire(this::computeParallaxSize); components = new KList<>(); registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java index 2698a694e..8460d8e3f 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedActuator.java @@ -32,7 +32,6 @@ public abstract class EngineAssignedActuator extends EngineAssignedComponent @BlockCoordinates @Override public void actuate(int x, int z, Hunk output, boolean multicore) { - Iris.debug("Engine Actuator[" + getName() + "] " + x + " " + z); onActuate(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java index 8e5bb8fb6..e69648b80 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineAssignedModifier.java @@ -33,7 +33,6 @@ public abstract class EngineAssignedModifier extends EngineAssignedComponent @BlockCoordinates @Override public void modify(int x, int z, Hunk output, boolean multicore) { - Iris.debug("Engine Modifier[" + getName() + "] " + x + " " + z); onModify(x, z, output, multicore); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 87c905692..9da22e093 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -51,7 +51,7 @@ public interface EngineMantle extends IObjectPlacer { Engine getEngine(); - Future getRadius(); + Integer getRadius(); KList getComponents(); @@ -224,7 +224,6 @@ public interface EngineMantle extends IObjectPlacer { return; } - Iris.debug("Engine Matter Insert " + x + " " + z); getMantle().iterateChunk(x, z, t, blocks::set); } diff --git a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index f0e105c87..8547643db 100644 --- a/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -177,7 +177,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun @Override public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random ignored, int x, int z, @NotNull BiomeGrid biome) { - Iris.debug("Generate Request " + world.getName() + " at: " + x + ", " + z); try { if(lastSeed != world.getSeed()) { @@ -188,14 +187,11 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun Iris.success("Updated Engine seed to " + lastSeed); } - Iris.debug("Generate Request [LOCKING] at: " + x + ", " + z); loadLock.acquire(); - Iris.debug("Generate Request [LOCKED] at: " + x + ", " + z); TerrainChunk tc = TerrainChunk.create(world, biome); Hunk blocks = Hunk.view((ChunkData) tc); Hunk biomes = Hunk.view((BiomeGrid) tc); this.world.bind(world); - Iris.debug("Generate Request [ENGINE] at: " + x + ", " + z); getEngine().generate(x * 16, z * 16, blocks, biomes, true); ChunkData c = tc.getRaw(); Iris.debug("Generated " + x + " " + z); From 7946221f0b6c8781c755b358fca222deb4f2b8da Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 07:33:45 -0400 Subject: [PATCH 22/39] f --- .../volmit/iris/engine/IrisEngineMantle.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index b19098805..c4f844900 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -63,8 +63,6 @@ public class IrisEngineMantle implements EngineMantle { private final KList components; private final int radius; private final AtomicCache radCache = new AtomicCache<>(); - private ProceduralStream> featureChunkStream; - private ProceduralStream> featureStream; public IrisEngineMantle(Engine engine) { this.engine = engine; @@ -74,21 +72,6 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); - featureChunkStream = ProceduralStream.of((x, z) - -> EngineMantle.super.getFeaturesInChunk(x.intValue(), z.intValue()), - Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(2048); - featureStream = ProceduralStream.of(EngineMantle.super::forEachFeature, - Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(8192); - } - - @ChunkCoordinates - public KList getFeaturesInChunk(int x, int z) { - return featureChunkStream.get(x, z); - } - - @BlockCoordinates - public KList forEachFeature(double x, double z) { - return featureStream.get(x, z); } @Override From 19ef66145730556b6fa238b0913a89002583b773 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 07:33:45 -0400 Subject: [PATCH 23/39] Revert "f" This reverts commit 7946221f0b6c8781c755b358fca222deb4f2b8da. --- .../volmit/iris/engine/IrisEngineMantle.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index c4f844900..b19098805 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -63,6 +63,8 @@ public class IrisEngineMantle implements EngineMantle { private final KList components; private final int radius; private final AtomicCache radCache = new AtomicCache<>(); + private ProceduralStream> featureChunkStream; + private ProceduralStream> featureStream; public IrisEngineMantle(Engine engine) { this.engine = engine; @@ -72,6 +74,21 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); + featureChunkStream = ProceduralStream.of((x, z) + -> EngineMantle.super.getFeaturesInChunk(x.intValue(), z.intValue()), + Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(2048); + featureStream = ProceduralStream.of(EngineMantle.super::forEachFeature, + Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(8192); + } + + @ChunkCoordinates + public KList getFeaturesInChunk(int x, int z) { + return featureChunkStream.get(x, z); + } + + @BlockCoordinates + public KList forEachFeature(double x, double z) { + return featureStream.get(x, z); } @Override From 0080110fadcf239f39e74890afe2f79691078ecf Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 09:31:15 -0400 Subject: [PATCH 24/39] Auto stash before revert of "f" --- .../com/volmit/iris/engine/IrisEngine.java | 23 ++-- .../volmit/iris/engine/IrisEngineMantle.java | 18 +-- .../volmit/iris/engine/IrisWorldManager.java | 5 +- .../volmit/iris/engine/framework/Engine.java | 2 +- .../iris/engine/mantle/EngineMantle.java | 33 +++-- .../components/MantleJigsawComponent.java | 10 +- .../object/feature/IrisFeaturePositional.java | 14 +- .../util/hunk/storage/MappedSyncHunk.java | 123 ++++++++++++++++++ .../com/volmit/iris/util/mantle/Mantle.java | 37 ++++-- .../volmit/iris/util/mantle/MantleChunk.java | 50 ++++--- .../iris/util/mantle/TectonicPlate.java | 4 +- .../iris/util/matter/slices/ZoneMatter.java | 1 + 12 files changed, 236 insertions(+), 84 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 225c3a795..fa0eb8e15 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -423,14 +423,21 @@ public class IrisEngine extends BlockPopulator implements Engine { switch (getDimension().getTerrainMode()) { case NORMAL -> { getMantle().generateMatter(x >> 4, z >> 4, multicore); - getTerrainActuator().actuate(x, z, vblocks, multicore); - getBiomeActuator().actuate(x, z, vbiomes, multicore); - getCaveModifier().modify(x, z, vblocks, multicore); - getRavineModifier().modify(x, z, vblocks, multicore); - getPostModifier().modify(x, z, vblocks, multicore); - getDecorantActuator().actuate(x, z, blocks, multicore); - getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore); - getDepositModifier().modify(x, z, blocks, multicore); + burst().burst( + () ->getTerrainActuator().actuate(x, z, vblocks, multicore), + () ->getBiomeActuator().actuate(x, z, vbiomes, multicore) + ); + burst().burst( + () ->getCaveModifier().modify(x, z, vblocks, multicore), + ()->getDecorantActuator().actuate(x, z, blocks, multicore), + ()->getRavineModifier().modify(x, z, vblocks, multicore), + ()->getPostModifier().modify(x, z, vblocks, multicore) + ); + burst().burst( + ()->getDecorantActuator().actuate(x, z, blocks, multicore), + ()->getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), + ()->getDepositModifier().modify(x, z, blocks, multicore) + ); } case ISLANDS -> { getTerrainActuator().actuate(x, z, vblocks, multicore); diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index b19098805..819b0f227 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -53,6 +53,7 @@ import org.bukkit.util.BlockVector; import java.io.File; import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -63,8 +64,6 @@ public class IrisEngineMantle implements EngineMantle { private final KList components; private final int radius; private final AtomicCache radCache = new AtomicCache<>(); - private ProceduralStream> featureChunkStream; - private ProceduralStream> featureStream; public IrisEngineMantle(Engine engine) { this.engine = engine; @@ -74,21 +73,6 @@ public class IrisEngineMantle implements EngineMantle { registerComponent(new MantleFeatureComponent(this)); registerComponent(new MantleJigsawComponent(this)); registerComponent(new MantleObjectComponent(this)); - featureChunkStream = ProceduralStream.of((x, z) - -> EngineMantle.super.getFeaturesInChunk(x.intValue(), z.intValue()), - Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(2048); - featureStream = ProceduralStream.of(EngineMantle.super::forEachFeature, - Interpolated.of((i) -> 0D, (i) -> new KList())).cache2D(8192); - } - - @ChunkCoordinates - public KList getFeaturesInChunk(int x, int z) { - return featureChunkStream.get(x, z); - } - - @BlockCoordinates - public KList forEachFeature(double x, double z) { - return featureStream.get(x, z); } @Override diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 81e6f7dab..c36f20cf5 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -211,7 +211,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { .shuffleCopy(RNG.r).stream() .filter(this::canSpawn), getData().getSpawnerLoader().streamAll(getEngine().getMantle() - .getFeaturesInChunk(c).stream() + .forEachFeature(c).stream() .flatMap((o) -> o.getFeature().getEntitySpawners().stream())) .filter(this::canSpawn)) .filter((i) -> i.isValid(biome)) @@ -294,6 +294,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private KList spawnRandomly(List types) { KList rarityTypes = new KList<>(); int totalRarity = 0; + for (IrisEntitySpawn i : types) { totalRarity += IRare.get(i); } @@ -344,7 +345,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { public void onChunkLoad(Chunk e, boolean generated) { if (generated) { energy += 1.2; - spawnIn(e, true); + J.a(() -> spawnIn(e, true), RNG.r.i(5, 50)); } else { energy += 0.3; } diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 0a3e8e02b..816880e04 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -243,7 +243,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat updateLighting(x, y, z, c); } } - }, MantleFlag.UPDATE); + }); getMetrics().getUpdates().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 9da22e093..1a072b7db 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -34,12 +34,14 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.mantle.MantleFlag; +import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import org.bukkit.Chunk; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; +import java.util.List; import java.util.concurrent.*; import java.util.function.Consumer; @@ -51,7 +53,7 @@ public interface EngineMantle extends IObjectPlacer { Engine getEngine(); - Integer getRadius(); + int getRadius(); KList getComponents(); @@ -166,15 +168,7 @@ public interface EngineMantle extends IObjectPlacer { } default int getRealRadius() { - try { - return (int) Math.ceil(getRadius().get() / 2D); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { - e.printStackTrace(); - } - - return 0; + return (int) Math.ceil(getRadius() / 2D); } @@ -195,8 +189,8 @@ public interface EngineMantle extends IObjectPlacer { BurstExecutor burst = burst().burst(); for (int i = -s; i <= s; i++) { - int xx = i + x; for (int j = -s; j <= s; j++) { + int xx = i + x; int zz = j + z; burst.queue(() -> { getComponents().forEach((f) -> generateMantleComponent(xx, zz, f, c)); @@ -229,20 +223,23 @@ public interface EngineMantle extends IObjectPlacer { @BlockCoordinates default void updateBlock(int x, int y, int z) { - getMantle().flag(x >> 4, z >> 4, MantleFlag.UPDATE, true); getMantle().set(x, y, z, true); } @ChunkCoordinates - default KList getFeaturesInChunk(Chunk c) { + default List getFeaturesInChunk(Chunk c) { return getFeaturesInChunk(c.getX(), c.getZ()); } @ChunkCoordinates - default KList getFeaturesInChunk(int x, int z) { - KList pos = new KList<>(); - getMantle().iterateChunk(x, z, IrisFeaturePositional.class, (a, b, c, f) -> pos.add(f), MantleFlag.FEATURE); - return pos; + default List getFeaturesInChunk(int x, int z) { + return getMantle().getChunk(x, z).getFeatures(); + } + + + @ChunkCoordinates + default KList forEachFeature(Chunk c) { + return forEachFeature((c.getX() << 4) + 8, (c.getZ() << 4) + 8); } @BlockCoordinates @@ -267,7 +264,7 @@ public interface EngineMantle extends IObjectPlacer { for (i = -s; i <= s; i++) { for (j = -s; j <= s; j++) { try { - for (IrisFeaturePositional k : getFeaturesInChunk(i + cx, j + cx)) { + for (IrisFeaturePositional k : getFeaturesInChunk(i + cx, j + cz)) { if (k.shouldFilter(x, z, getEngine().getComplex().getRng(), getData())) { pos.add(k); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 9462ca83a..b93907542 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -18,6 +18,8 @@ package com.volmit.iris.engine.mantle.components; +import com.google.gson.Gson; +import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.mantle.EngineMantle; @@ -27,24 +29,29 @@ import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructurePlacement; +import com.volmit.iris.engine.object.noise.NoiseStyle; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.CNG; import java.util.List; import java.util.function.Consumer; public class MantleJigsawComponent extends IrisMantleComponent { + private final CNG cng; + public MantleJigsawComponent(EngineMantle engineMantle) { super(engineMantle, MantleFlag.JIGSAW); + cng = NoiseStyle.STATIC.create(new RNG()); } @Override public void generateLayer(int x, int z, Consumer post) { - RNG rng = new RNG(Cache.key(x, z) + seed()); + RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z)); int xxx = 8 + (x << 4); int zzz = 8 + (z << 4); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); @@ -109,7 +116,6 @@ public class MantleJigsawComponent extends IrisMantleComponent { if (structure.getFeature().getBlockRadius() == 32) { structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3); } - getMantle().set(position.getX(), 0, position.getZ(), new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature())); } diff --git a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java index dc686bb91..0edd0b49b 100644 --- a/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java +++ b/src/main/java/com/volmit/iris/engine/object/feature/IrisFeaturePositional.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object.feature; import com.google.gson.Gson; +import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; @@ -63,7 +64,18 @@ public class IrisFeaturePositional { private static double BLOCK = 1D / 256D; // TODO: WARNING HEIGHT public static IrisFeaturePositional read(DataInputStream s) throws IOException { - return new Gson().fromJson(s.readUTF(), IrisFeaturePositional.class); + String sx = s.readUTF(); + try + { + return new Gson().fromJson(sx, IrisFeaturePositional.class); + } + + catch(Throwable e) + { + Iris.error(sx); + e.printStackTrace(); + throw new IOException(e); + } } public void write(DataOutputStream s) throws IOException { diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java new file mode 100644 index 000000000..ee2a79228 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/storage/MappedSyncHunk.java @@ -0,0 +1,123 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.storage; + +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.function.Consumer4; +import com.volmit.iris.util.function.Consumer4IO; +import com.volmit.iris.util.hunk.Hunk; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"DefaultAnnotationParam", "Lombok"}) +@Data +@EqualsAndHashCode(callSuper = false) +public class MappedSyncHunk extends StorageHunk implements Hunk { + private final Map data; + + public MappedSyncHunk(int w, int h, int d) { + super(w, h, d); + data = new HashMap<>(); + } + + public int getEntryCount() { + return data.size(); + } + + public boolean isMapped() { + return true; + } + + public boolean isEmpty() { + synchronized(data) + { + return data.isEmpty(); + } + } + + @Override + public void setRaw(int x, int y, int z, T t) { + synchronized(data) { + if (t == null) { + data.remove(index(x, y, z)); + return; + } + + data.put(index(x, y, z), t); + } + } + + private Integer index(int x, int y, int z) { + return (z * getWidth() * getHeight()) + (y * getWidth()) + x; + } + + @Override + public synchronized Hunk iterateSync(Consumer4 c) { + synchronized(data) + { + int idx, z; + + for (Map.Entry g : data.entrySet()) { + idx = g.getKey(); + z = idx / (getWidth() * getHeight()); + idx -= (z * getWidth() * getHeight()); + c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue()); + } + + return this; + } + } + + @Override + public synchronized Hunk iterateSyncIO(Consumer4IO c) throws IOException { + synchronized(data) + { + int idx, z; + + for (Map.Entry g : data.entrySet()) { + idx = g.getKey(); + z = idx / (getWidth() * getHeight()); + idx -= (z * getWidth() * getHeight()); + c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue()); + } + + return this; + } + } + + @Override + public void empty(T b) { + synchronized(data) + { + data.clear(); + } + } + + @Override + public T getRaw(int x, int y, int z) { + synchronized(data) + { + return data.get(index(x, y, z)); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 3265aaef7..38535fb5e 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.documentation.BlockCoordinates; @@ -115,6 +116,12 @@ public class Mantle { } } + @ChunkCoordinates + public MantleChunk getChunk(int x, int z) + { + return get(x>>5, z>>5).getOrCreate(x & 31, z & 31); + } + /** * Flag or unflag a chunk * @param x the chunk x @@ -146,22 +153,15 @@ public class Mantle { * @param z the chunk z * @param type the type of data to iterate * @param iterator the iterator (x,y,z,data) -> do stuff - * @param requiredFlags any required flags that must be met for this chunk to be iterated * @param the type of data to iterate */ @ChunkCoordinates - public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { + public void iterateChunk(int x, int z, Class type, Consumer4 iterator) { if(!hasTectonicPlate(x >> 5, z >> 5)) { return; } - for (MantleFlag i : requiredFlags) { - if (!hasFlag(x, z, i)) { - return; - } - } - get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator); } @@ -206,11 +206,20 @@ public class Mantle { return; } - Matter matter = get((x >> 4) >> 5, (z >> 4) >> 5) - .getOrCreate((x >> 4) & 31, (z >> 4) & 31) - .getOrCreate(y >> 4); - matter.slice(matter.getClass(t)) - .set(x & 15, y & 15, z & 15, t); + if(t instanceof IrisFeaturePositional) + { + get((x >> 4) >> 5, (z >> 4) >> 5) + .getOrCreate((x >> 4) & 31, (z >> 4) & 31).addFeature((IrisFeaturePositional) t); + } + + else + { + Matter matter = get((x >> 4) >> 5, (z >> 4) >> 5) + .getOrCreate((x >> 4) & 31, (z >> 4) & 31) + .getOrCreate(y >> 4); + matter.slice(matter.getClass(t)) + .set(x & 15, y & 15, z & 15, t); + } } /** @@ -235,7 +244,7 @@ public class Mantle { throw new RuntimeException("The Mantle is closed"); } - if(!hasTectonicPlate(x >> 5, z >> 5)) + if(!hasTectonicPlate((x >> 4) >> 5, (z >> 4) >> 5)) { return null; } diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index 85d248508..7675d78cc 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -18,17 +18,22 @@ package com.volmit.iris.util.mantle; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.MatterSlice; +import com.volmit.iris.util.matter.slices.ZoneMatter; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicIntegerArray; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -37,8 +42,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray; * Mantle Chunks are fully atomic & thread safe */ public class MantleChunk { + private static final ZoneMatter zm = new ZoneMatter(); private final AtomicIntegerArray flags; private final AtomicReferenceArray sections; + private final CopyOnWriteArrayList features; /** * Create a mantle chunk @@ -49,6 +56,7 @@ public class MantleChunk { public MantleChunk(int sectionHeight) { sections = new AtomicReferenceArray<>(sectionHeight); flags = new AtomicIntegerArray(MantleFlag.values().length); + features = new CopyOnWriteArrayList<>(); for (int i = 0; i < flags.length(); i++) { flags.set(i, 0); @@ -76,6 +84,13 @@ public class MantleChunk { sections.set(i, Matter.read(din)); } } + + short v = din.readShort(); + + for(int i = 0; i < v; i++) + { + features.add(zm.readNode(din)); + } } public void flag(MantleFlag flag, boolean f) { @@ -169,6 +184,13 @@ public class MantleChunk { dos.writeBoolean(false); } } + + dos.writeShort(features.size()); + + for(IrisFeaturePositional i : features) + { + zm.writeNode(i, dos); + } } private void trimSlice(int i) { @@ -186,26 +208,6 @@ public class MantleChunk { } } - public void iterate(Class type, Consumer4 iterator, BurstExecutor burst) { - for (int i = 0; i < sections.length(); i++) { - int finalI = i; - burst.queue(() -> { - int bs = (finalI << 4); - Matter matter = get(finalI); - - if (matter != null) { - MatterSlice t = matter.getSlice(type); - - if (t != null) { - t.iterateSync((a, b, c, f) -> iterator.accept(a, b + bs, c, f)); - } - } - }); - } - - burst.complete(); - } - public void iterate(Class type, Consumer4 iterator) { for (int i = 0; i < sections.length(); i++) { int bs = (i << 4); @@ -220,4 +222,12 @@ public class MantleChunk { } } } + + public void addFeature(IrisFeaturePositional t) { + features.add(t); + } + + public List getFeatures() { + return features; + } } diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index b78a32f2f..6df695c21 100644 --- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -19,9 +19,11 @@ package com.volmit.iris.util.mantle; import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.hunk.storage.ArrayHunk; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import java.io.*; @@ -140,7 +142,7 @@ public class TectonicPlate { @ChunkCoordinates private int index(int x, int z) { - return (x & 0x1F) + (z & 0x1F) * 32; + return Cache.to1D(x, z, 0, 32, 32); } /** diff --git a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java index 6201b08f1..652ac391f 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/ZoneMatter.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.matter.slices; +import com.volmit.iris.Iris; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.util.matter.Sliced; From b62e542801992a52e0f4136c098048e96ca7de99 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 09:42:49 -0400 Subject: [PATCH 25/39] "S" --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b32a90615..0df21934c 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.5' +version '1.7.5S' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris' From 33812b3f4a1d4cd922eabbf6a72258a7e0308dda Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 21:41:37 -0400 Subject: [PATCH 26/39] Fixes --- src/main/java/com/volmit/iris/Iris.java | 2 +- .../iris/core/project/SchemaBuilder.java | 5 +- .../com/volmit/iris/engine/IrisComplex.java | 39 +------- .../com/volmit/iris/engine/IrisEngine.java | 56 ++++------- .../engine/actuator/IrisBiomeActuator.java | 2 +- .../engine/actuator/IrisDecorantActuator.java | 2 +- .../actuator/IrisTerrainIslandActuator.java | 95 ------------------- .../actuator/IrisTerrainNormalActuator.java | 2 +- .../volmit/iris/engine/framework/Engine.java | 7 -- .../iris/engine/mantle/EngineMantle.java | 4 +- .../engine/modifier/IrisCaveModifier.java | 17 +--- .../engine/modifier/IrisDepositModifier.java | 2 +- .../engine/modifier/IrisPostModifier.java | 2 +- .../engine/object/block/IrisBlockData.java | 12 +-- .../object/dimensional/IrisDimension.java | 17 ---- .../dimensional/IrisDimensionIndex.java | 54 ----------- .../object/dimensional/IrisTerrainIsland.java | 50 ---------- .../object/dimensional/IrisTerrainMode.java | 29 ------ .../engine/object/objects/IrisObject.java | 2 +- .../iris/util/parallel/BurstExecutor.java | 32 +++++++ .../volmit/iris/util/parallel/MultiBurst.java | 36 +++++++ .../com/volmit/iris/util/scheduling/J.java | 1 - 22 files changed, 113 insertions(+), 355 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java delete mode 100644 src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java delete mode 100644 src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java delete mode 100644 src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 7bd1f59ab..e21764a34 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -699,7 +699,7 @@ public class Iris extends VolmitPlugin implements Listener { } } - public static synchronized void reportError(Throwable e) { + public static void reportError(Throwable e) { if (IrisSettings.get().getGeneral().isDebug()) { String n = e.getClass().getCanonicalName() + "-" + e.getStackTrace()[0].getClassName() + "-" + e.getStackTrace()[0].getLineNumber(); diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index c77d29000..989f3126e 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -32,6 +32,7 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.potion.PotionEffectType; import java.awt.*; +import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.List; @@ -536,8 +537,8 @@ public class SchemaBuilder { d.add("* Default Value is " + value); } } - } catch (Throwable e) { - Iris.reportError(e); + } catch (Throwable ignored) { + } description.forEach((g) -> d.add(g.trim())); diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 43a11c3d3..cfff636a1 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -30,7 +30,6 @@ import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; import com.volmit.iris.engine.object.decoration.IrisDecorationPart; import com.volmit.iris.engine.object.decoration.IrisDecorator; -import com.volmit.iris.engine.object.dimensional.IrisTerrainMode; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.noise.IrisGenerator; import com.volmit.iris.engine.object.noise.IrisInterpolator; @@ -65,9 +64,6 @@ public class IrisComplex implements DataProvider { private ProceduralStream regionStyleStream; private ProceduralStream regionIdentityStream; private ProceduralStream regionIDStream; - private ProceduralStream islandStream; - private ProceduralStream islandHeightStream; - private ProceduralStream islandDepthStream; private ProceduralStream bridgeStream; private ProceduralStream landBiomeStream; private ProceduralStream caveBiomeStream; @@ -86,8 +82,6 @@ public class IrisComplex implements DataProvider { private ProceduralStream heightFluidStream; private ProceduralStream trueHeightStream; private ProceduralStream slopeStream; - private ProceduralStream islandTopStream; - private ProceduralStream islandBottomStream; private ProceduralStream topSurfaceStream; private ProceduralStream rngStream; private ProceduralStream chunkRngStream; @@ -167,11 +161,6 @@ public class IrisComplex implements DataProvider { : regionStyleStream .selectRarity(engine.getDimension().getRegions(), (i) -> data.getRegionLoader().load(i)) .convertCached((s) -> data.getRegionLoader().load(s)).cache2D(cacheSize); - islandStream = regionStyleStream - .seededChance(rng.nextParallelRNG(29349), 23968888888L, - 1D / engine.getDimension().getIslandMode().getIslandChance()); - islandHeightStream = regionIdentityStream.style(rng.nextParallelRNG(330466), engine.getDimension().getIslandMode().getHeight(), data); - islandDepthStream = engine.getDimension().getIslandMode().getIslandDepth().stream(rng.nextParallelRNG(-39578888), data); regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i), String.valueOf(i * 38445).hashCode() * 3245556666L)); caveBiomeStream = regionStream.convert((r) -> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream() @@ -334,13 +323,11 @@ public class IrisComplex implements DataProvider { int heightf = (int) Math.round(getHeightStream().get(rx, rz)); int m = heightf; - if (engine.getDimension().isCarving() && engine.getDimension().getTerrainMode().equals(IrisTerrainMode.NORMAL)) { - if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { - m--; + if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { + m--; - while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { - m--; - } + while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) { + m--; } } @@ -367,27 +354,9 @@ public class IrisComplex implements DataProvider { d.hashCode()); }) .cache2D(cacheSize); - islandTopStream = islandStream.convertAware2D((i, x, z) -> - i ? heightStream.round() - .subtract(fluidHeight) - .add((xx, zz) -> getIslandHeight(xx.intValue(), zz.intValue(), engine.getDimension() - .getIslandMode().getIslandEdgeInterpolator())) - .get(x, z) : 0); - islandBottomStream = islandStream.convertAware2D((i, x, z) -> - i ? islandHeightStream.subtract(islandDepthStream).round().get(x, z) : 0); //@done } - private double getIslandHeight(int x, int z, IrisInterpolator interp) { - return interp.interpolate(x, z, (xx, zz) -> { - if (getIslandStream().get(xx, zz)) { - return getIslandHeightStream().get(xx, zz); - } - - return 0; - }); - } - private IrisRegion findRegion(IrisBiome focus, Engine engine) { for (IrisRegion i : engine.getDimension().getAllRegions(engine)) { if (i.getAllBiomeIds().contains(focus.getLoadKey())) { diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index fa0eb8e15..d6278b91b 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -26,7 +26,6 @@ import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.engine.actuator.IrisBiomeActuator; import com.volmit.iris.engine.actuator.IrisDecorantActuator; -import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; @@ -96,8 +95,7 @@ public class IrisEngine extends BlockPopulator implements Engine { private double maxBiomeLayerDensity; private double maxBiomeDecoratorDensity; private IrisComplex complex; - private EngineActuator terrainNormalActuator; - private EngineActuator terrainIslandActuator; + private EngineActuator terrainActuator; private EngineActuator decorantActuator; private EngineActuator biomeActuator; private EngineModifier depositModifier; @@ -146,8 +144,7 @@ public class IrisEngine extends BlockPopulator implements Engine { worldManager.close(); complex.close(); execution.close(); - terrainNormalActuator.close(); - terrainIslandActuator.close(); + terrainActuator.close(); decorantActuator.close(); biomeActuator.close(); depositModifier.close(); @@ -166,8 +163,7 @@ public class IrisEngine extends BlockPopulator implements Engine { worldManager = new IrisWorldManager(this); complex = new IrisComplex(this); execution = new IrisExecutionEnvironment(this); - terrainNormalActuator = new IrisTerrainNormalActuator(this); - terrainIslandActuator = new IrisTerrainIslandActuator(this); + terrainActuator = new IrisTerrainNormalActuator(this); decorantActuator = new IrisDecorantActuator(this); biomeActuator = new IrisBiomeActuator(this); depositModifier = new IrisDepositModifier(this); @@ -387,13 +383,6 @@ public class IrisEngine extends BlockPopulator implements Engine { }); } - public EngineActuator getTerrainActuator() { - return switch (getDimension().getTerrainMode()) { - case NORMAL -> getTerrainNormalActuator(); - case ISLANDS -> getTerrainIslandActuator(); - }; - } - @BlockCoordinates @Override public double modifyX(double x) { @@ -420,29 +409,22 @@ public class IrisEngine extends BlockPopulator implements Engine { PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t)); - switch (getDimension().getTerrainMode()) { - case NORMAL -> { - getMantle().generateMatter(x >> 4, z >> 4, multicore); - burst().burst( - () ->getTerrainActuator().actuate(x, z, vblocks, multicore), - () ->getBiomeActuator().actuate(x, z, vbiomes, multicore) - ); - burst().burst( - () ->getCaveModifier().modify(x, z, vblocks, multicore), - ()->getDecorantActuator().actuate(x, z, blocks, multicore), - ()->getRavineModifier().modify(x, z, vblocks, multicore), - ()->getPostModifier().modify(x, z, vblocks, multicore) - ); - burst().burst( - ()->getDecorantActuator().actuate(x, z, blocks, multicore), - ()->getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), - ()->getDepositModifier().modify(x, z, blocks, multicore) - ); - } - case ISLANDS -> { - getTerrainActuator().actuate(x, z, vblocks, multicore); - } - } + getMantle().generateMatter(x >> 4, z >> 4, multicore); + burst().burst(multicore, + () -> getTerrainActuator().actuate(x, z, vblocks, multicore), + () -> getBiomeActuator().actuate(x, z, vbiomes, multicore) + ); + burst().burst(multicore, + () -> getCaveModifier().modify(x, z, vblocks, multicore), + () -> getDecorantActuator().actuate(x, z, blocks, multicore), + () -> getRavineModifier().modify(x, z, vblocks, multicore), + () -> getPostModifier().modify(x, z, vblocks, multicore) + ); + burst().burst(multicore, + () -> getDecorantActuator().actuate(x, z, blocks, multicore), + () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), + () -> getDepositModifier().modify(x, z, blocks, multicore) + ); getMetrics().getTotal().put(p.getMilliseconds()); generated.incrementAndGet(); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index 226ebab98..347aad64c 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -68,7 +68,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { @Override public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor burst = burst().burst(); + BurstExecutor burst = burst().burst(multicore); for (int xf = 0; xf < h.getWidth(); xf++) { int finalXf = xf; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index e2a8b9e1c..60cab2592 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -90,7 +90,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor burst = burst().burst(); + BurstExecutor burst = burst().burst(multicore); for (int i = 0; i < output.getWidth(); i++) { int finalI = i; diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java deleted file mode 100644 index e9890d3ea..000000000 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.actuator; - -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.EngineAssignedActuator; -import com.volmit.iris.engine.object.biome.IrisBiome; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.documentation.BlockCoordinates; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import lombok.Getter; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; - -public class IrisTerrainIslandActuator extends EngineAssignedActuator { - private static final BlockData AIR = Material.AIR.createBlockData(); - private static final BlockData BEDROCK = Material.BEDROCK.createBlockData(); - private static final BlockData WEB = Material.COBWEB.createBlockData(); - private static final BlockData BLACK_GLASS = Material.BLACK_STAINED_GLASS.createBlockData(); - private static final BlockData WHITE_GLASS = Material.WHITE_STAINED_GLASS.createBlockData(); - private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData(); - @Getter - private final RNG rng; - private final boolean carving; - @Getter - private final int lastBedrock = -1; - - public IrisTerrainIslandActuator(Engine engine) { - super(engine, "TerrainIsland"); - rng = new RNG(engine.getWorld().seed()); - carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); - } - - @BlockCoordinates - @Override - public void onActuate(int x, int z, Hunk h, boolean multicore) { - PrecisionStopwatch p = PrecisionStopwatch.start(); - int i, zf, depth, surface, realX, realZ; - IrisBiome biome; - KList blocks, fblocks; - int hi, lo; - double hh; - - for (int xf = 0; xf < h.getWidth(); xf++) { - for (zf = 0; zf < h.getDepth(); zf++) { - realX = (int) modX(xf + x); - realZ = (int) modZ(zf + z); - - if (getComplex().getIslandStream().get(realX, realZ)) { - biome = getComplex().getTrueBiomeStream().get(realX, realZ); - hh = getComplex().getTrueHeightStream().get(realX, realZ) - getComplex().getFluidHeight(); - depth = (int) (getComplex().getIslandDepthStream().get(realX, realZ).intValue() + hh); - blocks = biome.generateLayers(realX, realZ, rng, depth, depth, getData(), getComplex()); - hi = getComplex().getIslandTopStream().get(realX, realZ); - lo = getComplex().getIslandBottomStream().get(realX, realZ); - - // 10 - // 6 - - // hf = 4 - - for (i = hi; i >= lo; i--) { - int hf = (i - hi); - if (blocks.hasIndex(hf)) { - h.set(xf, i, zf, blocks.get(hf)); - continue; - } - - h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); - } - } - } - } - - getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); - } -} diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index 91ec3d0f7..ef1ca77d3 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -55,7 +55,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - BurstExecutor e = getEngine().burst().burst(h.getWidth()); + BurstExecutor e = burst().burst(multicore); for (int xf = 0; xf < h.getWidth(); xf++) { int finalXf = xf; e.queue(() -> terrainSliver(x, z, finalXf, h)); diff --git a/src/main/java/com/volmit/iris/engine/framework/Engine.java b/src/main/java/com/volmit/iris/engine/framework/Engine.java index 816880e04..e7defb9aa 100644 --- a/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -434,13 +434,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat IrisDimension dim = getDimension(); dim.getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i)); - try { - dim.getDimensionalComposite().forEach((m) -> getData().getDimensionLoader().load(m.getDimension()).getAllBiomes(this).forEach((i) -> v.put(i.getLoadKey(), i))); - } catch (Throwable ignored) { - Iris.reportError(ignored); - - } - return v.v(); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 1a072b7db..cd7a8d7be 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -186,7 +186,7 @@ public interface EngineMantle extends IObjectPlacer { } }; int s = getRealRadius(); - BurstExecutor burst = burst().burst(); + BurstExecutor burst = burst().burst(multicore); for (int i = -s; i <= s; i++) { for (int j = -s; j <= s; j++) { @@ -204,7 +204,7 @@ public interface EngineMantle extends IObjectPlacer { { KList px = post.copy(); post.clear(); - burst().burst(px); + burst().burst(multicore, px); } } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java index 13ab2cd30..302752a9a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java @@ -55,20 +55,13 @@ public class IrisCaveModifier extends EngineAssignedModifier { } PrecisionStopwatch p = PrecisionStopwatch.start(); - if (multicore) { - BurstExecutor e = getEngine().burst().burst(a.getWidth()); - for (int i = 0; i < a.getWidth(); i++) { - int finalI = i; - e.queue(() -> modifySliver(x, z, finalI, a)); - } - - e.complete(); - } else { - for (int i = 0; i < a.getWidth(); i++) { - modifySliver(x, z, i, a); - } + BurstExecutor e = burst().burst(multicore); + for (int i = 0; i < a.getWidth(); i++) { + int finalI = i; + e.queue(() -> modifySliver(x, z, finalI, a)); } + e.complete(); getEngine().getMetrics().getCave().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index ce8c8bc30..3e2e7bb63 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -54,7 +54,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z); IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7); IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7); - BurstExecutor burst = burst().burst(); + BurstExecutor burst = burst().burst(multicore); for (IrisDepositGenerator k : getDimension().getDeposits()) { burst.queue(() -> generate(k, terrain, ro, x, z, false)); diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index d5daa6b2a..96630255a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -64,7 +64,7 @@ public class IrisPostModifier extends EngineAssignedModifier { PrecisionStopwatch p = PrecisionStopwatch.start(); AtomicInteger i = new AtomicInteger(); AtomicInteger j = new AtomicInteger(); - BurstExecutor burst = burst().burst(); + BurstExecutor burst = burst().burst(multicore); Hunk sync = output.synchronize(); for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) { burst.queue(() -> { diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java index 28ec3d367..693f5811e 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java @@ -193,17 +193,15 @@ public class IrisBlockData extends IrisRegistrant { } try { - return Integer.valueOf(string); - } catch (Throwable e) { - Iris.reportError(e); - + return Integer.parseInt(string); + } catch (Throwable ignored) { + // Checks } try { return Double.valueOf(string).intValue(); - } catch (Throwable e) { - Iris.reportError(e); - + } catch (Throwable ignored) { + // Checks } return string; diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 08050272d..6b9af843a 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -81,13 +81,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("The human readable name of this dimension") private String name = "A Dimension"; - @Desc("You can create mutliple dimensions on top of each other taking up less height of the same world. Such as the nether with a floor + ceiling.") - @ArrayType(min = 1, type = IrisDimensionIndex.class) - private KList dimensionalComposite = new KList<>(); - - @Desc("Create an inverted dimension in the sky (like the nether)") - private IrisDimension sky = null; - @RegistryListResource(IrisJigsawStructure.class) @Desc("If defined, Iris will place the given jigsaw structure where minecraft should place the overworld stronghold.") private String stronghold; @@ -285,12 +278,6 @@ public class IrisDimension extends IrisRegistrant { @Desc("Change the size of regions") private double regionZoom = 1; - @Desc("The terrain mode. NORMAL is normal... ISLANDS creates floating islands at varied heights") - private IrisTerrainMode terrainMode = IrisTerrainMode.NORMAL; - - @Desc("The configuration for island mode dimensions") - private IrisTerrainIsland islandMode = new IrisTerrainIsland(); - @Desc("Disable this to stop placing objects, entities, features & updates") private boolean useMantle = true; @@ -358,10 +345,6 @@ public class IrisDimension extends IrisRegistrant { }); } - public boolean hasSky() { - return getSky() != null; - } - public CNG getCoordFracture(RNG rng, int signature) { return coordFracture.aquire(() -> { diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java deleted file mode 100644 index 570e325aa..000000000 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimensionIndex.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.dimensional; - -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.RegistryListResource; -import com.volmit.iris.engine.object.annotations.Required; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@SuppressWarnings("DefaultAnnotationParam") -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Represents an index for dimensions to take up vertical slots in the same world") -@Data -@EqualsAndHashCode(callSuper = false) -public class IrisDimensionIndex { - @Required - @Desc("The weight of this dimension. If there are 2 dimensions, if the weight is the same on both, both dimensions will take up 128 blocks of height.") - private double weight = 1D; - - @Desc("If inverted is set to true, the dimension will be updide down in the world") - private boolean inverted = false; - - @Desc("Only one dimension layer should be set to primary. The primary dimension layer is where players spawn, and the biomes that the vanilla structure system uses to figure out what structures to place.") - private boolean primary = false; - - @Required - @RegistryListResource(IrisDimension.class) - @MinNumber(1) - @Desc("Name of dimension") - private String dimension = ""; -} diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java deleted file mode 100644 index 7b0df490f..000000000 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainIsland.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.dimensional; - -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MaxNumber; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.noise.IrisInterpolator; -import com.volmit.iris.engine.object.noise.IrisStyledRange; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@Accessors(chain = true) -@NoArgsConstructor -@AllArgsConstructor -@Desc("Translate objects") -@Data -public class IrisTerrainIsland { - @Desc("The height range") - private IrisStyledRange height = new IrisStyledRange().setMin(60).setMax(160); - - @Desc("How deep the island can get") - private IrisStyledRange islandDepth = new IrisStyledRange().setMin(60).setMax(160); - - @MinNumber(1) - @MaxNumber(10000) - @Desc("How often are regions islands instead of nothing?") - private double islandChance = 0.5; - - @Desc("Interpolate the edges of islands") - private IrisInterpolator islandEdgeInterpolator = new IrisInterpolator(); -} diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java deleted file mode 100644 index 8c9a162b0..000000000 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisTerrainMode.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2021 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.volmit.iris.engine.object.dimensional; - -import com.volmit.iris.engine.object.annotations.Desc; - -@Desc("Terrain modes are used to decide the generator type currently used") -public enum IrisTerrainMode { - @Desc("Normal terrain, similar to the vanilla overworld") - NORMAL, - @Desc("Island terrain, more similar to the end, but endless possibilities!") - ISLANDS -} diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java index 16d591103..d485d3aaf 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java @@ -281,7 +281,7 @@ public class IrisObject extends IrisRegistrant { this.h = din.readInt(); this.d = din.readInt(); if (!din.readUTF().equals("Iris V2 IOB;")) { - throw new IOException("Not V2 Format"); + return; } center = new BlockVector(w / 2, h / 2, d / 2); int s = din.readShort(); diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index bf2aa0fb9..b7edc9e89 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -29,6 +29,8 @@ import java.util.concurrent.*; public class BurstExecutor { private final ExecutorService executor; private final KList> futures; + @Setter + private boolean multicore = true; public BurstExecutor(ExecutorService executor, int burstSizeEstimate) { this.executor = executor; @@ -46,6 +48,16 @@ public class BurstExecutor { } public BurstExecutor queue(List r) { + if(!multicore) + { + for(Runnable i : new KList<>(r)) + { + i.run(); + } + + return this; + } + synchronized (futures) { for (Runnable i : new KList<>(r)) { queue(i); @@ -56,6 +68,16 @@ public class BurstExecutor { } public BurstExecutor queue(Runnable[] r) { + if(!multicore) + { + for(Runnable i : new KList<>(r)) + { + i.run(); + } + + return this; + } + synchronized (futures) { for (Runnable i : r) { queue(i); @@ -66,6 +88,11 @@ public class BurstExecutor { } public void complete() { + if(!multicore) + { + return; + } + synchronized (futures) { if (futures.isEmpty()) { return; @@ -85,6 +112,11 @@ public class BurstExecutor { } public boolean complete(long maxDur) { + if(!multicore) + { + return true; + } + synchronized (futures) { if (futures.isEmpty()) { return true; diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 3ea793079..6b21ddb21 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -72,10 +72,40 @@ public class MultiBurst { burst(r.length).queue(r).complete(); } + public void burst(boolean multicore, Runnable... r) { + if(multicore) + { + burst(r); + } + + else + { + sync(r); + } + } + public void burst(List r) { burst(r.size()).queue(r).complete(); } + public void burst(boolean multicore, List r) { + if(multicore) + { + burst(r); + } + + else { + sync(r); + } + } + + private void sync(List r) { + for(Runnable i : new KList<>(r)) + { + i.run(); + } + } + public void sync(Runnable... r) { for (Runnable i : r) { i.run(); @@ -96,6 +126,12 @@ public class MultiBurst { return burst(16); } + public BurstExecutor burst(boolean multicore) { + BurstExecutor b = burst(); + b.setMulticore(multicore); + return b; + } + public Future lazySubmit(Callable o) { return getService().submit(o); } diff --git a/src/main/java/com/volmit/iris/util/scheduling/J.java b/src/main/java/com/volmit/iris/util/scheduling/J.java index 0394dbd60..b5a38442e 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/J.java +++ b/src/main/java/com/volmit/iris/util/scheduling/J.java @@ -129,7 +129,6 @@ public class J { try { r.run(); } catch (Throwable e) { - Iris.reportError(e); return e; } From 6ed8b6d05814d9cdceb7f6d94a103d610d5e4d1c Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 21:46:01 -0400 Subject: [PATCH 27/39] Fix --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0df21934c..61541af83 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.5S' +version '1.7.6' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris' From 2a8e4f19af2cff5424f9a34be21856fd3c52058a Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sat, 21 Aug 2021 21:50:12 -0400 Subject: [PATCH 28/39] Stop closing production worlds --- .../java/com/volmit/iris/core/service/StudioSVC.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/service/StudioSVC.java b/src/main/java/com/volmit/iris/core/service/StudioSVC.java index 5adadda95..214c581a6 100644 --- a/src/main/java/com/volmit/iris/core/service/StudioSVC.java +++ b/src/main/java/com/volmit/iris/core/service/StudioSVC.java @@ -82,18 +82,6 @@ public class StudioSVC implements IrisService { IrisToolbelt.evacuate(i); IrisToolbelt.access(i).close(); } - - else - { - if(!IrisSettings.get().getGeneral().isKeepProductionOnReload()) - { - IrisToolbelt.evacuate(i); - IrisToolbelt.access(i).close(); - Iris.error("You cannot reload Iris while production worlds are active!"); - Iris.error("To prevent corrupted chunks, Iris is shutting the server down now!"); - Bukkit.shutdown(); - } - } } } } From 0e86d6fbdbd09f18a6adc69108ed4244b8cabd73 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:03:57 -0400 Subject: [PATCH 29/39] Libs --- build.gradle | 2 ++ src/main/resources/plugin.yml | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 61541af83..f3c953e31 100644 --- a/build.gradle +++ b/build.gradle @@ -187,6 +187,7 @@ dependencies { implementation 'net.kyori:adventure-api:4.8.1' // Dynamically Loaded + implementation 'io.timeandspace:smoothie-map:2.0.2' implementation 'it.unimi.dsi:fastutil:8.5.4' implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2' implementation 'org.zeroturnaround:zt-zip:1.14' @@ -195,4 +196,5 @@ dependencies { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'bsf:bsf:2.4.0' implementation 'rhino:js:1.7R2' + implementation 'com.github.ben-manes.caffeine:caffeine:3.0.3' } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 59767aa97..6163d903d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,14 +6,16 @@ authors: [ cyberpwn, NextdoorPsycho ] website: volmit.com description: More than a Dimension! libraries: - - org.zeroturnaround:zt-zip:1.14 - com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2 - - org.ow2.asm:asm:9.2 - - com.google.code.gson:gson:2.8.7 - - it.unimi.dsi:fastutil:8.5.4 + - com.github.ben-manes.caffeine:caffeine:3.0.3 + - io.timeandspace:smoothie-map:2.0.2 - com.google.guava:guava:30.1.1-jre - - bsf:bsf:2.4.0 + - com.google.code.gson:gson:2.8.7 + - org.zeroturnaround:zt-zip:1.14 + - it.unimi.dsi:fastutil:8.5.4 + - org.ow2.asm:asm:9.2 - rhino:js:1.7R2 + - bsf:bsf:2.4.0 commands: iris: aliases: [ ir, irs ] From beb80f0422214933dc93e1cd6b8d09868ccef465 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:04:24 -0400 Subject: [PATCH 30/39] Modernize B --- .../java/com/volmit/iris/util/data/B.java | 818 ++++++++---------- 1 file changed, 374 insertions(+), 444 deletions(-) diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java index 25fc1b483..9a09b0b81 100644 --- a/src/main/java/com/volmit/iris/util/data/B.java +++ b/src/main/java/com/volmit/iris/util/data/B.java @@ -22,7 +22,12 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.scheduling.ChronoLatch; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.ints.IntSets; +import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; +import it.unimi.dsi.fastutil.objects.ReferenceSet; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -33,388 +38,192 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; +import static org.bukkit.Material.*; + public class B { private static final Material AIR_MATERIAL = Material.AIR; private static final BlockData AIR = AIR_MATERIAL.createBlockData(); - private static final KSet nullBlockDataCache = new KSet<>(); - private static final KSet nullMaterialCache = new KSet<>(); - private static final KMap solidCache = new KMap<>(); - private static final KMap updatableCache = new KMap<>(); - private static final KMap foliageCache = new KMap<>(); - private static final KMap litCache = new KMap<>(); - private static final KMap decorantCache = new KMap<>(); - private static final KMap storageCache = new KMap<>(); - private static final KMap storageChestCache = new KMap<>(); + private static final IntSet decorantCache = buildDecorantCache(); + private static final IntSet foliageCache = buildFoliageCache(); + private static final IntSet storageCache = buildStorageCache(); + private static final IntSet storageChestCache = buildStorageChestCache(); + private static final IntSet litCache = buildLitCache(); private static final KMap blockDataCache = new KMap<>(); - private static final KMap materialCache = new KMap<>(); + private static final ChronoLatch clw = new ChronoLatch(1000); - public static boolean isWater(BlockData b) { - return b.getMaterial().equals(Material.WATER); + private static IntSet buildFoliageCache() { + IntSet b = new IntOpenHashSet(); + Arrays.stream(new Material[]{ + POPPY, + DANDELION, + CORNFLOWER, + SWEET_BERRY_BUSH, + CRIMSON_ROOTS, + WARPED_ROOTS, + NETHER_SPROUTS, + ALLIUM, + AZURE_BLUET, + BLUE_ORCHID, + POPPY, + DANDELION, + OXEYE_DAISY, + LILY_OF_THE_VALLEY, + WITHER_ROSE, + DARK_OAK_SAPLING, + ACACIA_SAPLING, + JUNGLE_SAPLING, + BIRCH_SAPLING, + SPRUCE_SAPLING, + OAK_SAPLING, + ORANGE_TULIP, + PINK_TULIP, + RED_TULIP, + WHITE_TULIP, + FERN, + LARGE_FERN, + GRASS, + TALL_GRASS + }).forEach((i) -> b.add(i.ordinal())); + + return IntSets.unmodifiable(b); } - public static BlockData getAir() { - return AIR; + private static IntSet buildDecorantCache() { + IntSet b = new IntOpenHashSet(); + Arrays.stream(new Material[]{ + + GRASS, + TALL_GRASS, + FERN, + LARGE_FERN, + CORNFLOWER, + SUNFLOWER, + CHORUS_FLOWER, + POPPY, + DANDELION, + OXEYE_DAISY, + ORANGE_TULIP, + PINK_TULIP, + RED_TULIP, + WHITE_TULIP, + LILAC, + DEAD_BUSH, + SWEET_BERRY_BUSH, + ROSE_BUSH, + WITHER_ROSE, + ALLIUM, + BLUE_ORCHID, + LILY_OF_THE_VALLEY, + CRIMSON_FUNGUS, + WARPED_FUNGUS, + RED_MUSHROOM, + BROWN_MUSHROOM, + CRIMSON_ROOTS, + AZURE_BLUET, + WEEPING_VINES, + WEEPING_VINES_PLANT, + WARPED_ROOTS, + NETHER_SPROUTS, + TWISTING_VINES, + TWISTING_VINES_PLANT, + SUGAR_CANE, + WHEAT, + POTATOES, + CARROTS, + BEETROOTS, + NETHER_WART, + SEA_PICKLE, + SEAGRASS, + ACACIA_BUTTON, + BIRCH_BUTTON, + CRIMSON_BUTTON, + DARK_OAK_BUTTON, + JUNGLE_BUTTON, + OAK_BUTTON, + POLISHED_BLACKSTONE_BUTTON, + SPRUCE_BUTTON, + STONE_BUTTON, + WARPED_BUTTON, + TORCH, + SOUL_TORCH + }).forEach((i) -> b.add(i.ordinal())); + + return IntSets.unmodifiable(b); } - public static Material getMaterial(String bdx) { - Material mat = getMaterialOrNull(bdx); + private static IntSet buildLitCache() { + IntSet b = new IntOpenHashSet(); + Arrays.stream(new Material[]{ + GLOWSTONE, + END_ROD, + SOUL_SAND, + TORCH, + REDSTONE_TORCH, + SOUL_TORCH, + REDSTONE_WALL_TORCH, + WALL_TORCH, + SOUL_WALL_TORCH, + LANTERN, + CANDLE, + JACK_O_LANTERN, + REDSTONE_LAMP, + MAGMA_BLOCK, + SHROOMLIGHT, + SEA_LANTERN, + SOUL_LANTERN, + FIRE, + SOUL_FIRE, + SEA_PICKLE, + BREWING_STAND, + REDSTONE_ORE, + }).forEach((i) -> b.add(i.ordinal())); - if (mat != null) { - return mat; - } - - return AIR_MATERIAL; + return IntSets.unmodifiable(b); } - public static Material getMaterialOrNull(String bdxx) { - String bx = bdxx.trim().toUpperCase(); + private static IntSet buildStorageCache() { + IntSet b = new IntOpenHashSet(); + Arrays.stream(new Material[]{ + CHEST, SMOKER, + TRAPPED_CHEST, + SHULKER_BOX, + WHITE_SHULKER_BOX, + ORANGE_SHULKER_BOX, + MAGENTA_SHULKER_BOX, + LIGHT_BLUE_SHULKER_BOX, + YELLOW_SHULKER_BOX, + LIME_SHULKER_BOX, + PINK_SHULKER_BOX, + GRAY_SHULKER_BOX, + LIGHT_GRAY_SHULKER_BOX, + CYAN_SHULKER_BOX, + PURPLE_SHULKER_BOX, + BLUE_SHULKER_BOX, + BROWN_SHULKER_BOX, + GREEN_SHULKER_BOX, + RED_SHULKER_BOX, + BLACK_SHULKER_BOX, + BARREL, + DISPENSER, + DROPPER, + HOPPER, + FURNACE, + BLAST_FURNACE + }).forEach((i) -> b.add(i.ordinal())); - if (nullMaterialCache.contains(bx)) { - return null; - } - - Material mat = materialCache.get(bx); - - if (mat != null) { - return mat; - } - - try { - Material mm = Material.valueOf(bx); - materialCache.put(bx, mm); - return mm; - } catch (Throwable e) { - Iris.reportError(e); - nullMaterialCache.add(bx); - return null; - } + return IntSets.unmodifiable(b); } - public static boolean isSolid(BlockData mat) { - return isSolid(mat.getMaterial()); - } + private static IntSet buildStorageChestCache() { + IntSet b = new IntOpenHashSet(storageCache); + b.remove(SMOKER.ordinal()); + b.remove(FURNACE.ordinal()); + b.remove(BLAST_FURNACE.ordinal()); - public static boolean isSolid(Material mat) { - Boolean solid = solidCache.get(mat); - - if (solid != null) { - return solid; - } - - solid = mat.isSolid(); - solidCache.put(mat, solid); - - return solid; - } - - public static BlockData getOrNull(String bdxf) { - try { - String bd = bdxf.trim(); - BlockData bdx = parseBlockData(bd); - - if (bdx == null) { - Iris.warn("Unknown Block Data '" + bd + "'"); - return AIR; - } - - return bdx; - } catch (Throwable e) { - Iris.reportError(e); - Iris.warn("Unknown Block Data '" + bdxf + "'"); - } - - return null; - } - - public static BlockData get(String bdxf) { - BlockData bd = getOrNull(bdxf); - - if (bd != null) { - return bd; - } - - return AIR; - } - - private static BlockData parseBlockDataOrNull(String ix) { - if (nullBlockDataCache.contains(ix)) { - return null; - } - - try { - BlockData bb = blockDataCache.get(ix); - - if (bb != null) { - return bb; - } - BlockData bx = null; - - if (ix.startsWith("oraxen:") && Iris.linkOraxen.supported()) { - bx = Iris.linkOraxen.getBlockDataFor(ix.split("\\Q:\\E")[1]); - } - - if (bx == null) { - bx = Bukkit.createBlockData(ix); - } - - if (bx instanceof Leaves && IrisSettings.get().getGenerator().preventLeafDecay) { - ((Leaves) bx).setPersistent(true); - } else if (bx instanceof Leaves) { - ((Leaves) bx).setPersistent(false); - } - - blockDataCache.put(ix, bx); - return bx; - } catch (Exception e) { - //Iris.reportError(e); - Iris.debug("Failed to load block \"" + ix + "\""); - - String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase(); - String state = block.contains("[") ? block.split("\\[")[1].split("\\]")[0] : ""; - Map stateMap = new HashMap<>(); - if (!state.equals("")) { - Arrays.stream(state.split(",")).forEach(s -> { - stateMap.put(s.split("=")[0], s.split("=")[1]); - }); - } - block = block.split("\\[")[0]; - - switch (block) { - case "cauldron" -> block = "water_cauldron"; //Would fail to load if it has a level parameter - case "grass_path" -> block = "dirt_path"; - case "concrete" -> block = "white_concrete"; - case "wool" -> block = "white_wool"; - case "beetroots" -> { - if (stateMap.containsKey("age")) { - String updated = stateMap.get("age"); - switch (updated) { - case "7" -> updated = "3"; - case "3", "4", "5" -> updated = "2"; - case "1", "2" -> updated = "1"; - } - stateMap.put("age", updated); - } - } - } - - Map newStates = new HashMap<>(); - for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid - try { - String newState = block + "[" + key + "=" + stateMap.get(key) + "]"; - Bukkit.createBlockData(newState); - - //If we get to here, the state is okay so we can use it - newStates.put(key, stateMap.get(key)); - - } catch (IllegalArgumentException ignored) { - } - } - - //Combine all the "good" states again - state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(",")); - if (!state.equals("")) state = "[" + state + "]"; - String newBlock = block + state; - Iris.debug("Converting " + ix + " to " + newBlock); - - try { - BlockData bd = Bukkit.createBlockData(newBlock); - blockDataCache.put(ix, bd); - return bd; - } catch (Throwable e1) { - Iris.reportError(e1); - } - - nullBlockDataCache.add(ix); - return null; - } - } - - private static BlockData parseBlockData(String ix) { - BlockData bd = parseBlockDataOrNull(ix); - - if (bd != null) { - return bd; - } - - Iris.warn("Unknown Block Data: " + ix); - - return AIR; - } - - public static boolean isStorage(BlockData mat) { - Material mm = mat.getMaterial(); - Boolean f = storageCache.get(mm); - - if (f != null) { - return f; - } - - f = mm.equals(B.getMaterial("CHEST")) - || mm.equals(B.getMaterial("TRAPPED_CHEST")) - || mm.equals(B.getMaterial("SHULKER_BOX")) - || mm.equals(B.getMaterial("WHITE_SHULKER_BOX")) - || mm.equals(B.getMaterial("ORANGE_SHULKER_BOX")) - || mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX")) - || mm.equals(B.getMaterial("YELLOW_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIME_SHULKER_BOX")) - || mm.equals(B.getMaterial("PINK_SHULKER_BOX")) - || mm.equals(B.getMaterial("GRAY_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX")) - || mm.equals(B.getMaterial("CYAN_SHULKER_BOX")) - || mm.equals(B.getMaterial("PURPLE_SHULKER_BOX")) - || mm.equals(B.getMaterial("BLUE_SHULKER_BOX")) - || mm.equals(B.getMaterial("BROWN_SHULKER_BOX")) - || mm.equals(B.getMaterial("GREEN_SHULKER_BOX")) - || mm.equals(B.getMaterial("RED_SHULKER_BOX")) - || mm.equals(B.getMaterial("BLACK_SHULKER_BOX")) - || mm.equals(B.getMaterial("BARREL")) - || mm.equals(B.getMaterial("DISPENSER")) - || mm.equals(B.getMaterial("DROPPER")) - || mm.equals(B.getMaterial("HOPPER")) - || mm.equals(B.getMaterial("FURNACE")) - || mm.equals(B.getMaterial("BLAST_FURNACE")) - || mm.equals(B.getMaterial("SMOKER")); - storageCache.put(mm, f); - return f; - } - - public static boolean isStorageChest(BlockData mat) { - if (!isStorage(mat)) { - return false; - } - - Material mm = mat.getMaterial(); - Boolean f = storageChestCache.get(mm); - - if (f != null) { - return f; - } - - f = mm.equals(B.getMaterial("CHEST")) - || mm.equals(B.getMaterial("TRAPPED_CHEST")) - || mm.equals(B.getMaterial("SHULKER_BOX")) - || mm.equals(B.getMaterial("WHITE_SHULKER_BOX")) - || mm.equals(B.getMaterial("ORANGE_SHULKER_BOX")) - || mm.equals(B.getMaterial("MAGENTA_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIGHT_BLUE_SHULKER_BOX")) - || mm.equals(B.getMaterial("YELLOW_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIME_SHULKER_BOX")) - || mm.equals(B.getMaterial("PINK_SHULKER_BOX")) - || mm.equals(B.getMaterial("GRAY_SHULKER_BOX")) - || mm.equals(B.getMaterial("LIGHT_GRAY_SHULKER_BOX")) - || mm.equals(B.getMaterial("CYAN_SHULKER_BOX")) - || mm.equals(B.getMaterial("PURPLE_SHULKER_BOX")) - || mm.equals(B.getMaterial("BLUE_SHULKER_BOX")) - || mm.equals(B.getMaterial("BROWN_SHULKER_BOX")) - || mm.equals(B.getMaterial("GREEN_SHULKER_BOX")) - || mm.equals(B.getMaterial("RED_SHULKER_BOX")) - || mm.equals(B.getMaterial("BLACK_SHULKER_BOX")) - || mm.equals(B.getMaterial("BARREL")) - || mm.equals(B.getMaterial("DISPENSER")) - || mm.equals(B.getMaterial("DROPPER")) - || mm.equals(B.getMaterial("HOPPER")); - storageChestCache.put(mm, f); - return f; - } - - public static boolean isLit(BlockData mat) { - Material mm = mat.getMaterial(); - Boolean f = litCache.get(mm); - - if (f != null) { - return f; - } - - f = mm.equals(B.getMaterial("GLOWSTONE")) - || mm.equals(B.getMaterial("END_ROD")) - || mm.equals(B.getMaterial("SOUL_SAND")) - || mm.equals(B.getMaterial("TORCH")) - || mm.equals(Material.REDSTONE_TORCH) - || mm.equals(B.getMaterial("SOUL_TORCH")) - || mm.equals(Material.REDSTONE_WALL_TORCH) - || mm.equals(Material.WALL_TORCH) - || mm.equals(B.getMaterial("SOUL_WALL_TORCH")) - || mm.equals(B.getMaterial("LANTERN")) - || mm.equals(Material.JACK_O_LANTERN) - || mm.equals(Material.REDSTONE_LAMP) - || mm.equals(Material.MAGMA_BLOCK) - || mm.equals(B.getMaterial("SHROOMLIGHT")) - || mm.equals(B.getMaterial("SEA_LANTERN")) - || mm.equals(B.getMaterial("SOUL_LANTERN")) - || mm.equals(Material.FIRE) - || mm.equals(B.getMaterial("SOUL_FIRE")) - || mm.equals(B.getMaterial("SEA_PICKLE")) - || mm.equals(Material.BREWING_STAND) - || mm.equals(Material.REDSTONE_ORE); - litCache.put(mm, f); - return f; - } - - public static boolean isUpdatable(BlockData mat) { - Boolean u = updatableCache.get(mat.getMaterial()); - - if (u != null) { - return u; - } - - u = isLit(mat) || isStorage(mat); - updatableCache.put(mat.getMaterial(), u); - return u; - } - - public static boolean isFoliage(Material d) { - return isFoliage(d.createBlockData()); - } - - public static boolean isFoliage(BlockData d) { - Boolean f = foliageCache.get(d.getMaterial()); - if (f != null) { - return f; - } - - if (isFluid(d) || isAir(d) || isSolid(d)) { - foliageCache.put(d.getMaterial(), false); - return false; - } - - Material mat = d.getMaterial(); - f = mat.equals(Material.POPPY) - || mat.equals(Material.DANDELION) - || mat.equals(B.getMaterial("CORNFLOWER")) - || mat.equals(B.getMaterial("SWEET_BERRY_BUSH")) - || mat.equals(B.getMaterial("CRIMSON_ROOTS")) - || mat.equals(B.getMaterial("WARPED_ROOTS")) - || mat.equals(B.getMaterial("NETHER_SPROUTS")) - || mat.equals(B.getMaterial("ALLIUM")) - || mat.equals(B.getMaterial("AZURE_BLUET")) - || mat.equals(B.getMaterial("BLUE_ORCHID")) - || mat.equals(B.getMaterial("POPPY")) - || mat.equals(B.getMaterial("DANDELION")) - || mat.equals(B.getMaterial("OXEYE_DAISY")) - || mat.equals(B.getMaterial("LILY_OF_THE_VALLEY")) - || mat.equals(B.getMaterial("WITHER_ROSE")) - || mat.equals(Material.DARK_OAK_SAPLING) - || mat.equals(Material.ACACIA_SAPLING) - || mat.equals(Material.JUNGLE_SAPLING) - || mat.equals(Material.BIRCH_SAPLING) - || mat.equals(Material.SPRUCE_SAPLING) - || mat.equals(Material.OAK_SAPLING) - || mat.equals(Material.ORANGE_TULIP) - || mat.equals(Material.PINK_TULIP) - || mat.equals(Material.RED_TULIP) - || mat.equals(Material.WHITE_TULIP) - || mat.equals(Material.FERN) - || mat.equals(Material.LARGE_FERN) - || mat.equals(Material.GRASS) - || mat.equals(Material.TALL_GRASS); - foliageCache.put(d.getMaterial(), f); - return f; + return IntSets.unmodifiable(b); } public static boolean canPlaceOnto(Material mat, Material onto) { - String key = mat.name() + "" + onto.name(); - if (isFoliage(mat)) { if (!isFoliagePlantable(onto)) { return false; @@ -447,86 +256,6 @@ public class B { return true; } - public static boolean isDecorant(BlockData m) { - Material mm = m.getMaterial(); - Boolean f = decorantCache.get(mm); - - if (f != null) { - return f; - } - - f = mm.equals(Material.GRASS) - || mm.equals(Material.TALL_GRASS) - || mm.equals(Material.FERN) - || mm.equals(Material.LARGE_FERN) - || mm.equals(B.getMaterial("CORNFLOWER")) - || mm.equals(Material.SUNFLOWER) - || mm.equals(Material.CHORUS_FLOWER) - || mm.equals(Material.POPPY) - || mm.equals(Material.DANDELION) - || mm.equals(Material.OXEYE_DAISY) - || mm.equals(Material.ORANGE_TULIP) - || mm.equals(Material.PINK_TULIP) - || mm.equals(Material.RED_TULIP) - || mm.equals(Material.WHITE_TULIP) - || mm.equals(Material.LILAC) - || mm.equals(Material.DEAD_BUSH) - || mm.equals(B.getMaterial("SWEET_BERRY_BUSH")) - || mm.equals(Material.ROSE_BUSH) - || mm.equals(B.getMaterial("WITHER_ROSE")) - || mm.equals(Material.ALLIUM) - || mm.equals(Material.BLUE_ORCHID) - || mm.equals(B.getMaterial("LILY_OF_THE_VALLEY")) - || mm.equals(B.getMaterial("CRIMSON_FUNGUS")) - || mm.equals(B.getMaterial("WARPED_FUNGUS")) - || mm.equals(Material.RED_MUSHROOM) - || mm.equals(Material.BROWN_MUSHROOM) - || mm.equals(B.getMaterial("CRIMSON_ROOTS")) - || mm.equals(B.getMaterial("AZURE_BLUET")) - || mm.equals(B.getMaterial("WEEPING_VINES")) - || mm.equals(B.getMaterial("WEEPING_VINES_PLANT")) - || mm.equals(B.getMaterial("WARPED_ROOTS")) - || mm.equals(B.getMaterial("NETHER_SPROUTS")) - || mm.equals(B.getMaterial("TWISTING_VINES")) - || mm.equals(B.getMaterial("TWISTING_VINES_PLANT")) - || mm.equals(Material.SUGAR_CANE) - || mm.equals(Material.WHEAT) - || mm.equals(Material.POTATOES) - || mm.equals(Material.CARROTS) - || mm.equals(Material.BEETROOTS) - || mm.equals(Material.NETHER_WART) - || mm.equals(B.getMaterial("SEA_PICKLE")) - || mm.equals(B.getMaterial("SEAGRASS")) - || mm.equals(B.getMaterial("ACACIA_BUTTON")) - || mm.equals(B.getMaterial("BIRCH_BUTTON")) - || mm.equals(B.getMaterial("CRIMSON_BUTTON")) - || mm.equals(B.getMaterial("DARK_OAK_BUTTON")) - || mm.equals(B.getMaterial("JUNGLE_BUTTON")) - || mm.equals(B.getMaterial("OAK_BUTTON")) - || mm.equals(B.getMaterial("POLISHED_BLACKSTONE_BUTTON")) - || mm.equals(B.getMaterial("SPRUCE_BUTTON")) - || mm.equals(B.getMaterial("STONE_BUTTON")) - || mm.equals(B.getMaterial("WARPED_BUTTON")) - || mm.equals(Material.TORCH) - || mm.equals(B.getMaterial("SOUL_TORCH")); - decorantCache.put(mm, f); - return f; - } - - public static KList get(KList find) { - KList b = new KList<>(); - - for (String i : find) { - BlockData bd = get(i); - - if (bd != null) { - b.add(bd); - } - } - - return b; - } - public static boolean isFoliagePlantable(BlockData d) { return d.getMaterial().equals(Material.GRASS_BLOCK) || d.getMaterial().equals(Material.ROOTED_DIRT) @@ -543,6 +272,207 @@ public class B { || d.equals(Material.PODZOL); } + public static boolean isWater(BlockData b) { + return b.getMaterial().equals(Material.WATER); + } + + public static BlockData getAir() { + return AIR; + } + + public static Material getMaterialOrNull(String bdx) { + try { + return Material.valueOf(bdx.trim().toUpperCase()); + } catch (Throwable e) { + Iris.reportError(e); + if(clw.flip()) + { + Iris.warn("Unknown Material: " + bdx); + } + return null; + } + } + + public static Material getMaterial(String bdx) { + Material m = getMaterialOrNull(bdx); + + if(m == null) + { + return AIR_MATERIAL; + } + + return m; + } + + public static boolean isSolid(BlockData mat) { + return mat.getMaterial().isSolid(); + } + + public static BlockData getOrNull(String bdxf) { + try { + String bd = bdxf.trim(); + BlockData bdx = parseBlockData(bd); + + if (bdx == null) { + if(clw.flip()) + { + Iris.warn("Unknown Block Data '" + bd + "'"); + } + return AIR; + } + + return bdx; + } catch (Throwable e) { + Iris.reportError(e); + + if(clw.flip()) + { + Iris.warn("Unknown Block Data '" + bdxf + "'"); + } + } + + return null; + } + + public static BlockData get(String bdxf) { + BlockData bd = getOrNull(bdxf); + + if (bd != null) { + return bd; + } + + return AIR; + } + + private static BlockData parseBlockData(String ix) { + try { + BlockData bb = blockDataCache.get(ix); + + if (bb != null) { + return bb; + } + + BlockData bx = null; + + if (ix.startsWith("oraxen:") && Iris.linkOraxen.supported()) { + bx = Iris.linkOraxen.getBlockDataFor(ix.split("\\Q:\\E")[1]); + } + + if (bx == null) { + bx = Bukkit.createBlockData(ix); + } + + if (bx instanceof Leaves && IrisSettings.get().getGenerator().preventLeafDecay) { + ((Leaves) bx).setPersistent(true); + } else if (bx instanceof Leaves) { + ((Leaves) bx).setPersistent(false); + } + + blockDataCache.put(ix, bx); + return bx; + } catch (Throwable e) { + if(clw.flip()) + { + Iris.warn("Unknown Block Data: " + ix); + } + + String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase(); + String state = block.contains("[") ? block.split("\\Q[\\E")[1].split("\\Q]\\E")[0] : ""; + Map stateMap = new HashMap<>(); + if (!state.equals("")) { + Arrays.stream(state.split(",")).forEach(s -> stateMap.put(s.split("=")[0], s.split("=")[1])); + } + block = block.split("\\Q[\\E")[0]; + + switch (block) { + case "cauldron" -> block = "water_cauldron"; + case "grass_path" -> block = "dirt_path"; + case "concrete" -> block = "white_concrete"; + case "wool" -> block = "white_wool"; + case "beetroots" -> { + if (stateMap.containsKey("age")) { + String updated = stateMap.get("age"); + switch (updated) { + case "7" -> updated = "3"; + case "3", "4", "5" -> updated = "2"; + case "1", "2" -> updated = "1"; + } + stateMap.put("age", updated); + } + } + } + + Map newStates = new HashMap<>(); + for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid + try { + String newState = block + "[" + key + "=" + stateMap.get(key) + "]"; + Bukkit.createBlockData(newState); + newStates.put(key, stateMap.get(key)); + + } catch (IllegalArgumentException ignored) { + } + } + + //Combine all the "good" states again + state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(",")); + if (!state.equals("")) state = "[" + state + "]"; + String newBlock = block + state; + Iris.debug("Converting " + ix + " to " + newBlock); + + try { + BlockData bd = Bukkit.createBlockData(newBlock); + blockDataCache.put(ix, bd); + return bd; + } catch (Throwable e1) { + Iris.reportError(e1); + } + + return null; + } + } + + public static boolean isStorage(BlockData mat) { + return storageCache.contains(mat.getMaterial().ordinal()); + } + + public static boolean isStorageChest(BlockData mat) { + return storageChestCache.contains(mat.getMaterial().ordinal()); + } + + public static boolean isLit(BlockData mat) { + return litCache.contains(mat.getMaterial().ordinal()); + } + + public static boolean isUpdatable(BlockData mat) { + return isLit(mat) || isStorage(mat); + } + + public static boolean isFoliage(Material d) { + return foliageCache.contains(d.ordinal()); + } + + public static boolean isFoliage(BlockData d) { + return isFoliage(d.getMaterial()); + } + + public static boolean isDecorant(BlockData m) { + return decorantCache.contains(m.getMaterial().ordinal()); + } + + public static KList get(KList find) { + KList b = new KList<>(); + + for (String i : find) { + BlockData bd = get(i); + + if (bd != null) { + b.add(bd); + } + } + + return b; + } + public static boolean isFluid(BlockData d) { return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.LAVA); } From 5bf6687f1f0a8402d7681aedb1da5b6db690c259 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:04:30 -0400 Subject: [PATCH 31/39] Compiling --- src/main/java/com/volmit/iris/Iris.java | 5 +- .../command/studio/CommandIrisStudio.java | 3 + .../studio/CommandIrisStudioCompile.java | 68 +++++++++ .../volmit/iris/core/project/IrisProject.java | 135 +++++++++++++++++- .../iris/core/project/loader/IrisData.java | 56 +++++++- .../core/project/loader/IrisRegistrant.java | 4 + .../engine/modifier/IrisCaveModifier.java | 4 +- .../iris/engine/object/biome/IrisBiome.java | 7 + .../engine/object/block/IrisBlockData.java | 7 + .../iris/engine/object/cave/IrisCave.java | 7 + .../iris/engine/object/common/IrisScript.java | 7 + .../object/dimensional/IrisDimension.java | 7 + .../iris/engine/object/entity/IrisEntity.java | 7 + .../engine/object/jigsaw/IrisJigsawPiece.java | 7 + .../engine/object/jigsaw/IrisJigsawPool.java | 7 + .../object/jigsaw/IrisJigsawStructure.java | 7 + .../engine/object/loot/IrisLootTable.java | 7 + .../iris/engine/object/mods/IrisMod.java | 7 + .../engine/object/noise/IrisExpression.java | 7 + .../engine/object/noise/IrisGenerator.java | 7 + .../engine/object/objects/IrisObject.java | 7 + .../engine/object/regional/IrisRegion.java | 7 + .../engine/object/spawners/IrisSpawner.java | 7 + .../scheduling/jobs/ParallelQueueJob.java | 42 ++++++ .../iris/util/scheduling/jobs/QueueJob.java | 21 +-- 25 files changed, 434 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java create mode 100644 src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index e21764a34..46b66ae70 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -18,7 +18,6 @@ package com.volmit.iris; -import com.google.gson.Gson; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.command.CommandIris; import com.volmit.iris.core.command.PermissionIris; @@ -32,6 +31,7 @@ import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; +import com.volmit.iris.engine.object.block.IrisBlockData; import com.volmit.iris.engine.object.common.IrisWorld; import com.volmit.iris.engine.object.compat.IrisCompat; import com.volmit.iris.engine.object.dimensional.IrisDimension; @@ -49,7 +49,6 @@ import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.io.JarScanner; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.*; import com.volmit.iris.util.reflect.ShadeFix; @@ -117,12 +116,10 @@ public class Iris extends VolmitPlugin implements Listener { sender.setTag(getTag()); instance = this; compat = IrisCompat.configured(getDataFile("compat.json")); - linkMultiverseCore = new MultiverseCoreLink(); linkOraxen = new OraxenLink(); linkMythicMobs = new MythicMobsLink(); configWatcher = new FileWatcher(getDataFile("settings.json")); - services.values().forEach(IrisService::onEnable); services.values().forEach(this::registerListener); } diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java index 993cdf13f..ada87b74f 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudio.java @@ -32,6 +32,9 @@ public class CommandIrisStudio extends MortarCommand { @Command private CommandIrisStudioExecute execute; + @Command + private CommandIrisStudioCompile compile; + @Command private CommandIrisStudioOpen open; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java new file mode 100644 index 000000000..6aacda65a --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioCompile.java @@ -0,0 +1,68 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.core.command.studio; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.project.IrisProject; +import com.volmit.iris.core.service.ConversionSVC; +import com.volmit.iris.core.service.StudioSVC; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.jobs.Job; +import com.volmit.iris.util.scheduling.jobs.JobCollection; + +public class CommandIrisStudioCompile extends MortarCommand { + public CommandIrisStudioCompile() { + super("compile"); + requiresPermission(Iris.perm.studio); + setDescription("Compiles a pack for speed"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + if (!IrisSettings.get().isStudio()) { + sender.sendMessage("To use Iris Studio, please enable studio in Iris/settings.json"); + return true; + } + + if(args.length == 0) + { + sender.sendMessage(getArgsUsage()); + return true; + } + + IrisProject project = new IrisProject(Iris.instance.getDataFolder(StudioSVC.WORKSPACE_NAME, args[0])); + project.compile(sender); + + return true; + } + + @Override + protected String getArgsUsage() { + return "[project]"; + } +} diff --git a/src/main/java/com/volmit/iris/core/project/IrisProject.java b/src/main/java/com/volmit/iris/core/project/IrisProject.java index bc4564a3b..875175bdc 100644 --- a/src/main/java/com/volmit/iris/core/project/IrisProject.java +++ b/src/main/java/com/volmit/iris/core/project/IrisProject.java @@ -22,6 +22,7 @@ import com.google.gson.Gson; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.core.project.loader.ResourceLoader; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -30,6 +31,7 @@ import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.object.entity.IrisEntity; import com.volmit.iris.engine.object.loot.IrisLootTable; import com.volmit.iris.engine.object.noise.IrisGenerator; +import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.spawners.IrisSpawner; @@ -38,6 +40,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.exceptions.IrisException; +import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONArray; @@ -48,6 +51,10 @@ import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.O; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import com.volmit.iris.util.scheduling.jobs.Job; +import com.volmit.iris.util.scheduling.jobs.JobCollection; +import com.volmit.iris.util.scheduling.jobs.ParallelQueueJob; +import com.volmit.iris.util.scheduling.jobs.QueueJob; import lombok.Data; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -443,7 +450,6 @@ public class IrisProject { return null; } - public static int clean(VolmitSender s, File clean) { int c = 0; if (clean.isDirectory()) { @@ -499,4 +505,131 @@ public class IrisProject { } } } + + public void compile(VolmitSender sender) { + IrisData data = IrisData.get(getPath()); + KList jobs = new KList(); + KList files = new KList(); + KList objects = new KList(); + files(getPath(), files); + filesObjects(getPath(), objects); + + jobs.add(new ParallelQueueJob() { + @Override + public void execute(File f) { + try { + JSONObject p = new JSONObject(IO.readAll(f)); + fixBlocks(p); + scanForErrors(data, f, p, sender); + IO.writeAll(f, p.toString(4)); + + } catch (Throwable e) { + sender.sendMessage(C.RED + "JSON Error "+ f.getPath() + ": " + e.getMessage()); + } + } + + @Override + public String getName() { + return "JSON"; + } + }.queue(files)); + + jobs.add(new ParallelQueueJob() { + @Override + public void execute(File f) { + try { + IrisObject o = new IrisObject(0,0,0); + o.read(f); + + if(o.getBlocks().isEmpty()) + { + sender.sendMessage(C.RED + "IOB " + f.getPath() + " has 0 blocks!"); + } + + if(o.getW() == 0 || o.getH() == 0 || o.getD() == 0) + { + sender.sendMessage(C.RED + "IOB " + f.getPath() + " is not 3D!"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public String getName() { + return "IOB"; + } + }.queue(objects)); + new JobCollection("Compile", jobs).execute(sender); + } + + private void scanForErrors(IrisData data, File f, JSONObject p, VolmitSender sender) { + String key = data.toLoadKey(f); + ResourceLoader loader = data.getTypedLoaderFor(f); + + if(loader == null) + { + sender.sendMessage("Can't find loader for " + f.getPath()); + return; + } + + IrisRegistrant load = loader.load(key); + load.scanForErrors(p, sender); + } + + public void files(File clean, KList files) { + if (clean.isDirectory()) { + for (File i : clean.listFiles()) { + files(i, files); + } + } else if (clean.getName().endsWith(".json")) { + try { + files.add(clean); + } catch (Throwable e) { + Iris.reportError(e); + } + } + } + + public void filesObjects(File clean, KList files) { + if (clean.isDirectory()) { + for (File i : clean.listFiles()) { + filesObjects(i, files); + } + } else if (clean.getName().endsWith(".iob")) { + try { + files.add(clean); + } catch (Throwable e) { + Iris.reportError(e); + } + } + } + + private void fixBlocks(JSONObject obj) { + for (String i : obj.keySet()) { + Object o = obj.get(i); + + if (i.equals("block") && o instanceof String && !o.toString().trim().isEmpty() && !o.toString().contains(":")) { + obj.put(i, "minecraft:" + o); + } + + if (o instanceof JSONObject) { + fixBlocks((JSONObject) o); + } else if (o instanceof JSONArray) { + fixBlocks((JSONArray) o); + } + } + } + + private void fixBlocks(JSONArray obj) { + for (int i = 0; i < obj.length(); i++) { + Object o = obj.get(i); + + if (o instanceof JSONObject) { + fixBlocks((JSONObject) o); + } else if (o instanceof JSONArray) { + fixBlocks((JSONArray) o); + } + } + } } diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java index dbb52eb4d..518a151ab 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisData.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisData.java @@ -19,6 +19,7 @@ package com.volmit.iris.core.project.loader; import com.volmit.iris.Iris; +import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockData; @@ -43,8 +44,9 @@ import com.volmit.iris.util.math.RNG; import lombok.Data; import java.io.File; -import java.util.Objects; +import java.util.*; import java.util.function.Function; +import java.util.stream.Collectors; @Data public class IrisData { @@ -89,6 +91,23 @@ public class IrisData { dataLoaders.v().forEach(IrisData::cleanupEngine); } + public ResourceLoader getTypedLoaderFor(File f) { + String[] k = f.getPath().split("\\Q"+File.separator+"\\E"); + + for(String i : k) + { + for(ResourceLoader j : loaders.values()) + { + if(j.getFolderName().equals(i)) + { + return j; + } + } + } + + return null; + } + public void cleanupEngine() { if(engine != null && engine.isClosed()) @@ -311,4 +330,39 @@ public class IrisData { return null; } + + public String toLoadKey(File f) { + if(f.getPath().startsWith(getDataFolder().getPath())) + { + String[] full = f.getPath().split("\\Q" + File.separator + "\\E"); + String[] df = getDataFolder().getPath().split("\\Q" + File.separator + "\\E"); + String g = ""; + boolean m = true; + for(int i = 0; i < full.length; i++) + { + if(i >= df.length) + { + if(m) + { + m = false; + continue; + } + + g += "/" + full[i]; + } + } + + String ff = g.toString().substring(1).split("\\Q.\\E")[0]; + return ff; + } + + else + { + Iris.error("Forign file from loader " + f.getPath() + " (loader realm: " + getDataFolder().getPath() + ")"); + } + + Iris.error("Failed to load " + f.getPath() + " (loader realm: " + getDataFolder().getPath() + ")"); + + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java index c457f19b4..40072e565 100644 --- a/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java +++ b/src/main/java/com/volmit/iris/core/project/loader/IrisRegistrant.java @@ -24,6 +24,8 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.common.IrisScript; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.Data; import java.awt.*; @@ -55,4 +57,6 @@ public abstract class IrisRegistrant { return getLoadFile(); } + + public abstract void scanForErrors(JSONObject p, VolmitSender sender); } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java index 302752a9a..a4d6517f2 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisCaveModifier.java @@ -237,7 +237,7 @@ public class IrisCaveModifier extends EngineAssignedModifier { } public boolean canAir(Material m, BlockData caveFluid) { - return (B.isSolid(m) || + return (m.isSolid() || (B.isDecorant(m.createBlockData())) || m.equals(Material.AIR) || m.equals(caveFluid.getMaterial()) || m.equals(B.getMaterial("CAVE_AIR"))) @@ -249,6 +249,6 @@ public class IrisCaveModifier extends EngineAssignedModifier { } public boolean can(Material m) { - return B.isSolid(m) && !m.equals(Material.BEDROCK); + return m.isSolid() && !m.equals(Material.BEDROCK); } } diff --git a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java index 4994393f9..e086f36cd 100644 --- a/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java +++ b/src/main/java/com/volmit/iris/engine/object/biome/IrisBiome.java @@ -48,8 +48,10 @@ import com.volmit.iris.util.data.B; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.VanillaBiomeMap; import com.volmit.iris.util.inventorygui.RandomColor; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CNG; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -696,4 +698,9 @@ public class IrisBiome extends IrisRegistrant implements IRare { public String getTypeName() { return "Biome"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java index 693f5811e..df29b7a01 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java @@ -26,6 +26,8 @@ import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.B; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -216,4 +218,9 @@ public class IrisBlockData extends IrisRegistrant { public String getTypeName() { return "Block"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java index 740933cac..13483cd7d 100644 --- a/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java +++ b/src/main/java/com/volmit/iris/engine/object/cave/IrisCave.java @@ -24,11 +24,13 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.noise.IrisWorm; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.B; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.Worm; import com.volmit.iris.util.noise.Worm3; import com.volmit.iris.util.noise.WormIterator3; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -56,4 +58,9 @@ public class IrisCave extends IrisRegistrant { public String getTypeName() { return "Cave"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java index 413b488e9..0ad77ac6b 100644 --- a/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java +++ b/src/main/java/com/volmit/iris/engine/object/common/IrisScript.java @@ -19,6 +19,8 @@ package com.volmit.iris.engine.object.common; import com.volmit.iris.core.project.loader.IrisRegistrant; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.Data; import lombok.EqualsAndHashCode; @@ -48,4 +50,9 @@ public class IrisScript extends IrisRegistrant { public String toString() { return source; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 6b9af843a..0c9aa95eb 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -50,9 +50,11 @@ import com.volmit.iris.engine.object.villager.IrisVillagerOverride; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CNG; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -543,4 +545,9 @@ public class IrisDimension extends IrisRegistrant { public String getTypeName() { return "Dimension"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java index e9d10dd5f..b78044a1c 100644 --- a/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/entity/IrisEntity.java @@ -32,7 +32,9 @@ import com.volmit.iris.engine.object.meta.IrisEffect; import com.volmit.iris.engine.object.spawners.IrisSurface; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.C; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.AllArgsConstructor; @@ -380,4 +382,9 @@ public class IrisEntity extends IrisRegistrant { public String getTypeName() { return "Entity"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java index 87e9e2526..054db8418 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPiece.java @@ -30,6 +30,8 @@ import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; import com.volmit.iris.engine.object.objects.ObjectPlaceMode; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -136,4 +138,9 @@ public class IrisJigsawPiece extends IrisRegistrant { public String getTypeName() { return "Jigsaw Piece"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java index 35316d0ea..8dd1a8aeb 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawPool.java @@ -24,6 +24,8 @@ import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.RegistryListResource; import com.volmit.iris.engine.object.annotations.Required; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -54,4 +56,9 @@ public class IrisJigsawPool extends IrisRegistrant { public String getTypeName() { return "Jigsaw Pool"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java index af36ce9fa..c786948ca 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java @@ -24,6 +24,8 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.feature.IrisFeature; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -144,4 +146,9 @@ public class IrisJigsawStructure extends IrisRegistrant { public String getTypeName() { return "Jigsaw Structure"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java index 2f6a2656e..221781d44 100644 --- a/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java +++ b/src/main/java/com/volmit/iris/engine/object/loot/IrisLootTable.java @@ -25,7 +25,9 @@ import com.volmit.iris.engine.object.annotations.MinNumber; import com.volmit.iris.engine.object.annotations.Required; import com.volmit.iris.engine.object.meta.InventorySlotType; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -96,4 +98,9 @@ public class IrisLootTable extends IrisRegistrant { public String getTypeName() { return "Loot"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java index 0dc83583e..19d4d4476 100644 --- a/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java +++ b/src/main/java/com/volmit/iris/engine/object/mods/IrisMod.java @@ -25,6 +25,8 @@ import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObjectReplace; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -113,4 +115,9 @@ public class IrisMod extends IrisRegistrant { public String getTypeName() { return "Mod"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java index 578070b1d..977cf1e4d 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisExpression.java @@ -28,7 +28,9 @@ import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.stream.ProceduralStream; import com.volmit.iris.util.stream.interpolation.Interpolated; import lombok.AllArgsConstructor; @@ -128,4 +130,9 @@ public class IrisExpression extends IrisRegistrant { public String getTypeName() { return "Expression"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java index 6a1c0d12c..f61c171db 100644 --- a/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java +++ b/src/main/java/com/volmit/iris/engine/object/noise/IrisGenerator.java @@ -26,8 +26,10 @@ import com.volmit.iris.engine.object.common.IRare; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.interpolation.IrisInterpolation; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CellGenerator; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -295,4 +297,9 @@ public class IrisGenerator extends IrisRegistrant { public String getTypeName() { return "Generator"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java index d485d3aaf..8c6ade3d5 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java @@ -31,10 +31,12 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.B; import com.volmit.iris.util.interpolation.IrisInterpolation; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.AxisAlignedBB; import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.IrisLock; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -994,4 +996,9 @@ public class IrisObject extends IrisRegistrant { public String getTypeName() { return "Object"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java index c24ea2ab8..728d99c80 100644 --- a/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java +++ b/src/main/java/com/volmit/iris/engine/object/regional/IrisRegion.java @@ -44,8 +44,10 @@ import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.VanillaBiomeMap; import com.volmit.iris.util.inventorygui.RandomColor; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CNG; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -572,4 +574,9 @@ public class IrisRegion extends IrisRegistrant implements IRare { public String getTypeName() { return "Region"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java index ece3c420c..2a0e98687 100644 --- a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java +++ b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java @@ -28,6 +28,8 @@ import com.volmit.iris.engine.object.basic.IrisWeather; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.entity.IrisEntitySpawn; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.plugin.VolmitSender; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -106,4 +108,9 @@ public class IrisSpawner extends IrisRegistrant { public String getTypeName() { return "Spawner"; } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } } diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java new file mode 100644 index 000000000..579b5303d --- /dev/null +++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/ParallelQueueJob.java @@ -0,0 +1,42 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.scheduling.jobs; + +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; + +public abstract class ParallelQueueJob extends QueueJob { + @Override + public void execute() { + while (queue.isNotEmpty()) { + BurstExecutor b = MultiBurst.burst.burst(queue.size()); + KList q = queue.copy(); + queue.clear(); + for(T i : q) + { + b.queue(() -> { + execute(i); + completeWork(); + }); + } + b.complete(); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/QueueJob.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/QueueJob.java index 4ee511545..6d0338b7e 100644 --- a/src/main/java/com/volmit/iris/util/scheduling/jobs/QueueJob.java +++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/QueueJob.java @@ -18,27 +18,32 @@ package com.volmit.iris.util.scheduling.jobs; +import com.sun.jna.platform.unix.X11; import com.volmit.iris.util.collection.KList; +import java.util.concurrent.atomic.AtomicInteger; + public abstract class QueueJob implements Job { - private final KList queue; - private int totalWork; - private int completed; + final KList queue; + protected int totalWork; + private AtomicInteger completed; public QueueJob() { totalWork = 0; - completed = 0; + completed = new AtomicInteger(0); queue = new KList<>(); } - public void queue(T t) { + public QueueJob queue(T t) { queue.add(t); totalWork++; + return this; } - public void queue(KList f) { + public QueueJob queue(KList f) { queue.addAll(f); totalWork += f.size(); + return this; } public abstract void execute(T t); @@ -54,7 +59,7 @@ public abstract class QueueJob implements Job { @Override public void completeWork() { - completed++; + completed.incrementAndGet(); } @Override @@ -64,6 +69,6 @@ public abstract class QueueJob implements Job { @Override public int getWorkCompleted() { - return completed; + return completed.get(); } } From 4a6d58c36e0656e92331af4d5516487474b6a9ad Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:30:39 -0400 Subject: [PATCH 32/39] Locky overrides --- .../volmit/iris/core/project/IrisProject.java | 69 ++++++++++++------- .../iris/engine/jigsaw/PlannedStructure.java | 6 +- .../object/jigsaw/IrisJigsawStructure.java | 6 +- .../java/com/volmit/iris/util/data/B.java | 14 ++-- .../volmit/iris/util/plugin/VolmitSender.java | 3 + 5 files changed, 64 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/project/IrisProject.java b/src/main/java/com/volmit/iris/core/project/IrisProject.java index 875175bdc..1a949fdc7 100644 --- a/src/main/java/com/volmit/iris/core/project/IrisProject.java +++ b/src/main/java/com/volmit/iris/core/project/IrisProject.java @@ -39,6 +39,7 @@ import com.volmit.iris.engine.platform.PlatformChunkGenerator; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.exceptions.IrisException; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; @@ -514,26 +515,6 @@ public class IrisProject { files(getPath(), files); filesObjects(getPath(), objects); - jobs.add(new ParallelQueueJob() { - @Override - public void execute(File f) { - try { - JSONObject p = new JSONObject(IO.readAll(f)); - fixBlocks(p); - scanForErrors(data, f, p, sender); - IO.writeAll(f, p.toString(4)); - - } catch (Throwable e) { - sender.sendMessage(C.RED + "JSON Error "+ f.getPath() + ": " + e.getMessage()); - } - } - - @Override - public String getName() { - return "JSON"; - } - }.queue(files)); - jobs.add(new ParallelQueueJob() { @Override public void execute(File f) { @@ -543,12 +524,16 @@ public class IrisProject { if(o.getBlocks().isEmpty()) { - sender.sendMessage(C.RED + "IOB " + f.getPath() + " has 0 blocks!"); + sender.sendMessageRaw("" + f.getPath() + + "'>- IOB " + f.getName() + " has 0 blocks!"); } if(o.getW() == 0 || o.getH() == 0 || o.getD() == 0) { - sender.sendMessage(C.RED + "IOB " + f.getPath() + " is not 3D!"); + sender.sendMessageRaw("" + f.getPath() + "\nThe width height or depth has a zero in it (bad format)" + + "'>- IOB " + f.getName() + " is not 3D!"); } } catch (IOException e) { e.printStackTrace(); @@ -560,6 +545,30 @@ public class IrisProject { return "IOB"; } }.queue(objects)); + + jobs.add(new ParallelQueueJob() { + @Override + public void execute(File f) { + try { + JSONObject p = new JSONObject(IO.readAll(f)); + fixBlocks(p); + scanForErrors(data, f, p, sender); + IO.writeAll(f, p.toString(4)); + + } catch (Throwable e) { + sender.sendMessageRaw("" + f.getPath() + + "\n" +e.getMessage() + + "'>- JSON Error " + f.getName()); + } + } + + @Override + public String getName() { + return "JSON"; + } + }.queue(files)); + new JobCollection("Compile", jobs).execute(sender); } @@ -569,14 +578,28 @@ public class IrisProject { if(loader == null) { - sender.sendMessage("Can't find loader for " + f.getPath()); + sender.sendMessageBasic("Can't find loader for " + f.getPath()); return; } IrisRegistrant load = loader.load(key); + compare(load.getClass(), p, sender, new KList<>()); load.scanForErrors(p, sender); } + public void compare(Class c, JSONObject j, VolmitSender sender, KList path) + { + try + { + Object o = c.getClass().getConstructor().newInstance(); + } + + catch(Throwable e) + { + + } + } + public void files(File clean, KList files) { if (clean.isDirectory()) { for (File i : clean.listFiles()) { diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 9983bbf0d..0acdc9617 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -114,9 +114,9 @@ public class PlannedStructure { int xx = i.getPosition().getX() + sx; int zz = i.getPosition().getZ() + sz; int offset = i.getPosition().getY() - startHeight; - int height = (i.getStructure().getStructure().getLockY() != -1 - ? i.getStructure().getStructure().getLockY() - : placer.getHighest(xx, zz, getData())) + offset + (v.getH() / 2); + int height = (i.getStructure().getStructure().getLockY() == -1 ? i.getStructure().getStructure().getOverrideYRange() != null + ? (int)i.getStructure().getStructure().getOverrideYRange().get(rng, xx, zz, getData()) + : i.getStructure().getStructure().getLockY() : placer.getHighest(xx, zz, getData())) + offset + (v.getH() / 2); if (options.getMode().equals(ObjectPlaceMode.PAINT) || options.isVacuum()) { height = -1; diff --git a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java index c786948ca..f643b8567 100644 --- a/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java +++ b/src/main/java/com/volmit/iris/engine/object/jigsaw/IrisJigsawStructure.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.project.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.feature.IrisFeature; +import com.volmit.iris.engine.object.noise.IrisStyledRange; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.plugin.VolmitSender; @@ -61,7 +62,10 @@ public class IrisJigsawStructure extends IrisRegistrant { @Desc("If set to true, iris will look for any pieces with only one connector in valid pools for edge connectors and attach them to 'terminate' the paths/piece connectors. Essentially it caps off ends. For example in a village, Iris would add houses to the ends of roads where possible. For terminators to be selected, they can only have one connector or they wont be chosen.") private boolean terminate = true; - @Desc("Set to lock the starting peice to a y coordinate, otherwise the surface will be used.") + @Desc("Override the y range instead of placing on the height map") + private IrisStyledRange overrideYRange = null; + + @Desc("Force Y to a specific value") private int lockY = -1; private transient AtomicCache maxDimension = new AtomicCache<>(); diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java index 9a09b0b81..18baabf4d 100644 --- a/src/main/java/com/volmit/iris/util/data/B.java +++ b/src/main/java/com/volmit/iris/util/data/B.java @@ -26,8 +26,6 @@ import com.volmit.iris.util.scheduling.ChronoLatch; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSets; -import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; -import it.unimi.dsi.fastutil.objects.ReferenceSet; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -64,8 +62,6 @@ public class B { ALLIUM, AZURE_BLUET, BLUE_ORCHID, - POPPY, - DANDELION, OXEYE_DAISY, LILY_OF_THE_VALLEY, WITHER_ROSE, @@ -91,7 +87,6 @@ public class B { private static IntSet buildDecorantCache() { IntSet b = new IntOpenHashSet(); Arrays.stream(new Material[]{ - GRASS, TALL_GRASS, FERN, @@ -147,6 +142,7 @@ public class B { TORCH, SOUL_TORCH }).forEach((i) -> b.add(i.ordinal())); + b.addAll(foliageCache); return IntSets.unmodifiable(b); } @@ -168,6 +164,7 @@ public class B { JACK_O_LANTERN, REDSTONE_LAMP, MAGMA_BLOCK, + LIGHT, SHROOMLIGHT, SEA_LANTERN, SOUL_LANTERN, @@ -184,7 +181,8 @@ public class B { private static IntSet buildStorageCache() { IntSet b = new IntOpenHashSet(); Arrays.stream(new Material[]{ - CHEST, SMOKER, + CHEST, + SMOKER, TRAPPED_CHEST, SHULKER_BOX, WHITE_SHULKER_BOX, @@ -230,7 +228,9 @@ public class B { } } - if (onto.equals(Material.AIR) || onto.equals(B.getMaterial("CAVE_AIR")) || onto.equals(B.getMaterial("VOID_AIR"))) { + if (onto.equals(Material.AIR) || + onto.equals(B.getMaterial("CAVE_AIR")) + || onto.equals(B.getMaterial("VOID_AIR"))) { return false; } diff --git a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java index 4ccdc31e3..c74811b2a 100644 --- a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java +++ b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java @@ -309,6 +309,9 @@ public class VolmitSender implements CommandSender { } } + public void sendMessageBasic(String message) { + s.sendMessage(C.translateAlternateColorCodes('&', getTag() + message)); + } public void sendMessageRaw(String message) { if (message.contains("")) { From ae79f9be6617f295f8ce44439d606b55d7f67b39 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:45:48 -0400 Subject: [PATCH 33/39] Fix noise explorer --- .../iris/core/gui/NoiseExplorerGUI.java | 2 +- .../iris/util/parallel/BurstExecutor.java | 27 ------------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index 36a631e17..66ab5bd39 100644 --- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -213,7 +213,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List }); } - e.complete(1000); + e.complete(); gg.drawImage(img, 0, 0, getParent().getWidth() * accuracy, getParent().getHeight() * accuracy, (img, infoflags, x, y, width, height) -> true); } diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index b7edc9e89..c81e47f77 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -110,31 +110,4 @@ public class BurstExecutor { } } } - - public boolean complete(long maxDur) { - if(!multicore) - { - return true; - } - - synchronized (futures) { - if (futures.isEmpty()) { - return true; - } - - try { - try { - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(maxDur, TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - return false; - } - futures.clear(); - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); - Iris.reportError(e); - } - } - - return false; - } } From 28e41a0ae988692effaa946aafe7182f5021589e Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:49:41 -0400 Subject: [PATCH 34/39] Fix B --- src/main/java/com/volmit/iris/util/data/B.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java index 18baabf4d..e072a5ab4 100644 --- a/src/main/java/com/volmit/iris/util/data/B.java +++ b/src/main/java/com/volmit/iris/util/data/B.java @@ -41,8 +41,8 @@ import static org.bukkit.Material.*; public class B { private static final Material AIR_MATERIAL = Material.AIR; private static final BlockData AIR = AIR_MATERIAL.createBlockData(); - private static final IntSet decorantCache = buildDecorantCache(); private static final IntSet foliageCache = buildFoliageCache(); + private static final IntSet decorantCache = buildDecorantCache(); private static final IntSet storageCache = buildStorageCache(); private static final IntSet storageChestCache = buildStorageChestCache(); private static final IntSet litCache = buildLitCache(); From 858c5a27adad839a1aab635bb90a701da68aa614 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:49:51 -0400 Subject: [PATCH 35/39] Sync post --- .../java/com/volmit/iris/engine/IrisEngine.java | 8 +++++--- .../iris/engine/modifier/IrisPostModifier.java | 14 +++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index d6278b91b..69584183b 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -417,11 +417,13 @@ public class IrisEngine extends BlockPopulator implements Engine { burst().burst(multicore, () -> getCaveModifier().modify(x, z, vblocks, multicore), () -> getDecorantActuator().actuate(x, z, blocks, multicore), - () -> getRavineModifier().modify(x, z, vblocks, multicore), - () -> getPostModifier().modify(x, z, vblocks, multicore) + () -> getRavineModifier().modify(x, z, vblocks, multicore) ); + + getDecorantActuator().actuate(x, z, blocks, multicore); + getPostModifier().modify(x, z, vblocks, multicore); + burst().burst(multicore, - () -> getDecorantActuator().actuate(x, z, blocks, multicore), () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), () -> getDepositModifier().modify(x, z, blocks, multicore) ); diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index 96630255a..5b772153a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -64,19 +64,15 @@ public class IrisPostModifier extends EngineAssignedModifier { PrecisionStopwatch p = PrecisionStopwatch.start(); AtomicInteger i = new AtomicInteger(); AtomicInteger j = new AtomicInteger(); - BurstExecutor burst = burst().burst(multicore); Hunk sync = output.synchronize(); for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) { - burst.queue(() -> { - for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { - int ii = i.get(); - int jj = j.get(); - post(ii, jj, sync, ii + x, jj + z); - } - }); + for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { + int ii = i.get(); + int jj = j.get(); + post(ii, jj, sync, ii + x, jj + z); + } } - burst.complete(); getEngine().getMetrics().getPost().put(p.getMilliseconds()); } From 7933f5e357d8ee67c58abaf37ecb751ce026e809 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 03:55:39 -0400 Subject: [PATCH 36/39] Fix height placement on structures --- .../iris/engine/jigsaw/PlannedStructure.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 0acdc9617..9cdaf127b 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -114,9 +114,26 @@ public class PlannedStructure { int xx = i.getPosition().getX() + sx; int zz = i.getPosition().getZ() + sz; int offset = i.getPosition().getY() - startHeight; - int height = (i.getStructure().getStructure().getLockY() == -1 ? i.getStructure().getStructure().getOverrideYRange() != null - ? (int)i.getStructure().getStructure().getOverrideYRange().get(rng, xx, zz, getData()) - : i.getStructure().getStructure().getLockY() : placer.getHighest(xx, zz, getData())) + offset + (v.getH() / 2); + int height = 0; + + if(i.getStructure().getStructure().getLockY() == -1) + { + if(i.getStructure().getStructure().getOverrideYRange() != null) + { + height = (int)i.getStructure().getStructure().getOverrideYRange().get(rng, xx, zz, getData()); + } + + else + { + height = placer.getHighest(xx, zz, getData()); + } + } + + else{ + height = i.getStructure().getStructure().getLockY(); + } + + height += offset + (v.getH() / 2); if (options.getMode().equals(ObjectPlaceMode.PAINT) || options.isVacuum()) { height = -1; From 44acfc7ec80e9ad5a41bd1294d94822c69f5786f Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Sun, 22 Aug 2021 04:22:16 -0400 Subject: [PATCH 37/39] Fix surfaces underwater --- .../actuator/IrisTerrainNormalActuator.java | 130 +++++++++--------- 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index ef1ca77d3..56fce5f95 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -66,70 +66,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); } - public void generateGround(int realX, int realZ, int xf, int zf, Hunk h, int surface, int bottom, int height, int fluidOrHeight, IrisBiome biome) - { - if(surface == bottom || surface-1 == bottom) - { - return; - } - - KList blocks = null; - KList fblocks = null; - int depth,fdepth; - - for (int i = surface; i >= bottom; i--) { - if (i >= h.getHeight()) { - continue; - } - - if (i == 0) { - if (getDimension().isBedrock()) { - h.set(xf, i, zf, BEDROCK); - lastBedrock = i; - continue; - } - } - - if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, height)) { - continue; - } - - if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, height, getData())) { - continue; - } - - if (i > height && i <= fluidOrHeight) { - fdepth = fluidOrHeight - i; - - if (fblocks == null) { - fblocks = biome.generateSeaLayers(realX, realZ, rng, fluidOrHeight - height, getData()); - } - - if (fblocks.hasIndex(fdepth)) { - h.set(xf, i, zf, fblocks.get(fdepth)); - continue; - } - - h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); - continue; - } - - if (i <= height) { - depth = surface - i; - if (blocks == null) { - blocks = biome.generateLayers(realX, realZ, rng, surface - bottom, surface, getData(), getComplex()); - } - - if (blocks.hasIndex(depth)) { - h.set(xf, i, zf, blocks.get(depth)); - continue; - } - - h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); - } - } - } - private int fluidOrHeight(int height) { return Math.max(getDimension().getFluidHeight(), height); @@ -145,12 +81,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator */ @BlockCoordinates public void terrainSliver(int x, int z, int xf, Hunk h) { - int i, realX, realZ, hf, he; + int zf, realX, realZ, hf, he; IrisBiome biome; - for (i = 0; i < h.getDepth(); i++) { + for (zf = 0; zf < h.getDepth(); zf++) { realX = (int) modX(xf + x); - realZ = (int) modZ(i + z); + realZ = (int) modZ(zf + z); biome = getComplex().getTrueBiomeStream().get(realX, realZ); he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); @@ -159,7 +95,65 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator continue; } - generateGround(realX, realZ, xf, i, h, hf, 0, he, hf, biome); + KList blocks = null; + KList fblocks = null; + int depth,fdepth; + + for (int i = hf; i >= 0; i--) { + if (i >= h.getHeight()) { + continue; + } + + if (i == 0) { + if (getDimension().isBedrock()) { + h.set(xf, i, zf, BEDROCK); + lastBedrock = i; + continue; + } + } + + if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, he)) { + continue; + } + + if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, he, getData())) { + continue; + } + + if (i > he && i <= hf) { + fdepth = hf - i; + + if (fblocks == null) { + fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData()); + } + + if (fblocks.hasIndex(fdepth)) { + h.set(xf, i, zf, fblocks.get(fdepth)); + continue; + } + + h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); + continue; + } + + if (i <= he) { + depth = he - i; + if (blocks == null) { + blocks = biome.generateLayers(realX, realZ, rng, + he, + he, + getData(), + getComplex()); + } + + if (blocks.hasIndex(depth)) { + h.set(xf, i, zf, blocks.get(depth)); + continue; + } + + h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); + } + } } } } From 9d62113388ca015290c5f11637b960fd6533f291 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Mon, 23 Aug 2021 03:12:17 -0400 Subject: [PATCH 38/39] Performance Improvements --- build.gradle | 2 +- .../com/volmit/iris/core/IrisSettings.java | 14 +- .../methods/AsyncPregenMethod.java | 2 +- .../methods/MedievalPregenMethod.java | 2 +- .../volmit/iris/core/tools/IrisToolbelt.java | 4 +- .../com/volmit/iris/engine/IrisEngine.java | 6 +- .../engine/data/chunk/MCATerrainChunk.java | 8 +- .../iris/engine/mantle/EngineMantle.java | 9 +- .../iris/engine/mantle/MantleComponent.java | 2 +- .../iris/engine/mantle/MantleWriter.java | 149 ++++++++++++++++++ .../components/MantleFeatureComponent.java | 17 +- .../components/MantleJigsawComponent.java | 24 ++- .../components/MantleObjectComponent.java | 21 +-- .../engine/platform/HeadlessGenerator.java | 9 +- .../com/volmit/iris/util/mantle/Mantle.java | 20 +++ .../com/volmit/iris/util/matter/Matter.java | 12 +- .../com/volmit/iris/util/nbt/mca/Chunk.java | 6 +- .../volmit/iris/util/nbt/mca/NBTWorld.java | 71 ++++----- .../com/volmit/iris/util/nbt/mca/Section.java | 17 +- .../volmit/iris/util/parallel/MultiBurst.java | 3 +- 20 files changed, 292 insertions(+), 106 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java diff --git a/build.gradle b/build.gradle index f3c953e31..1b677aafb 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.6' +version '1.7.7' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris' diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java index b69ec5b6c..7025af4e3 100644 --- a/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -20,6 +20,7 @@ package com.volmit.iris.core; import com.google.gson.Gson; import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.basic.IrisRange; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONException; @@ -56,6 +57,11 @@ public class IrisSettings { return getParallax().getParallaxRegionEvictionMS(); } + public static int getPriority(int c) + { + return Math.max(Math.min(c, Thread.MAX_PRIORITY), Thread.MIN_PRIORITY); + } + public static int getThreadCount(int c) { if (c < 2 && c >= 0) { return 2; @@ -82,13 +88,7 @@ public class IrisSettings { @Data public static class IrisSettingsConcurrency { - public int engineThreadCount = -1; - public int engineThreadPriority = 6; - public int pregenThreadCount = -1; - public int pregenThreadPriority = 8; - public int miscThreadCount = -4; - public int miscThreadPriority = 3; - public boolean unstableLockingHeuristics = false; + public int parallelism = -1; } @Data diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 64a1fbe53..c3f8c7169 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -114,7 +114,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { @Override public void generateChunk(int x, int z, PregenListener listener) { - if (future.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) { + if (future.size() > IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())) { // TODO: FIX waitForChunks(); } diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java index 6a378f786..d796ce182 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/MedievalPregenMethod.java @@ -95,7 +95,7 @@ public class MedievalPregenMethod implements PregeneratorMethod { @Override public void generateChunk(int x, int z, PregenListener listener) { - if (futures.size() > IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())) { + if (futures.size() > IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism())) { waitForChunks(); } diff --git a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java index 8277f117b..dfb0ca4b0 100644 --- a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -128,7 +128,7 @@ public class IrisToolbelt { return pregenerate(task, new HeadlessPregenMethod(((HeadlessGenerator) gen).getWorld(), (HeadlessGenerator) gen)); } - return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()))); + return pregenerate(task, new HybridPregenMethod(gen.getEngine().getWorld().realWorld(), IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism()))); } /** @@ -144,7 +144,7 @@ public class IrisToolbelt { return pregenerate(task, access(world)); } - return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount()))); + return pregenerate(task, new HybridPregenMethod(world, IrisSettings.getThreadCount((int) IrisSettings.get().getConcurrency().getParallelism()))); } /** diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 69584183b..d2a5cd90a 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -48,6 +48,7 @@ import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.PrecisionStopwatch; @@ -408,8 +409,8 @@ public class IrisEngine extends BlockPopulator implements Engine { try { PrecisionStopwatch p = PrecisionStopwatch.start(); Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t)); - getMantle().generateMatter(x >> 4, z >> 4, multicore); + burst().burst(multicore, () -> getTerrainActuator().actuate(x, z, vblocks, multicore), () -> getBiomeActuator().actuate(x, z, vbiomes, multicore) @@ -420,12 +421,11 @@ public class IrisEngine extends BlockPopulator implements Engine { () -> getRavineModifier().modify(x, z, vblocks, multicore) ); - getDecorantActuator().actuate(x, z, blocks, multicore); getPostModifier().modify(x, z, vblocks, multicore); burst().burst(multicore, () -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore), - () -> getDepositModifier().modify(x, z, blocks, multicore) + () -> getDepositModifier().modify(x, z, vblocks, multicore) ); getMetrics().getTotal().put(p.getMilliseconds()); diff --git a/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java b/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java index 523bb88c0..c09941c07 100644 --- a/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java +++ b/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.data.chunk; +import com.volmit.iris.Iris; import com.volmit.iris.core.nms.BiomeBaseInjector; import com.volmit.iris.util.nbt.mca.Chunk; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -69,7 +70,7 @@ public class MCATerrainChunk implements TerrainChunk { @Override public void setBiome(int x, int y, int z, Biome bio) { - writer.setBiome(ox + x, y, oz + z, bio); + mcaChunk.setBiomeAt((ox + x) & 15, y, (oz + z) & 15, writer.getBiomeId(bio)); } @Override @@ -91,6 +92,11 @@ public class MCATerrainChunk implements TerrainChunk { return; } + if(blockData == null) + { + Iris.error("NULL BD"); + } + mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index cd7a8d7be..597012502 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -37,6 +37,7 @@ import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Chunk; import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; @@ -187,13 +188,13 @@ public interface EngineMantle extends IObjectPlacer { }; int s = getRealRadius(); BurstExecutor burst = burst().burst(multicore); - + MantleWriter writer = getMantle().write(this, x, z, s * 2); for (int i = -s; i <= s; i++) { for (int j = -s; j <= s; j++) { int xx = i + x; int zz = j + z; burst.queue(() -> { - getComponents().forEach((f) -> generateMantleComponent(xx, zz, f, c)); + getComponents().forEach((f) -> generateMantleComponent(writer, xx, zz, f, c)); }); } } @@ -208,8 +209,8 @@ public interface EngineMantle extends IObjectPlacer { } } - default void generateMantleComponent(int x, int z, MantleComponent c, Consumer post) { - getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(x, z, post)); + default void generateMantleComponent(MantleWriter writer, int x, int z, MantleComponent c, Consumer post) { + getMantle().raiseFlag(x, z, c.getFlag(), () -> c.generateLayer(writer, x, z, post)); } @ChunkCoordinates diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java index d2755f897..7a7444250 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleComponent.java @@ -62,5 +62,5 @@ public interface MantleComponent { MantleFlag getFlag(); @ChunkCoordinates - void generateLayer(int x, int z, Consumer post); + void generateLayer(MantleWriter writer, int x, int z, Consumer post); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java new file mode 100644 index 000000000..c304c7e5d --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java @@ -0,0 +1,149 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.engine.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.IrisEngineMantle; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.object.common.IObjectPlacer; +import com.volmit.iris.engine.object.feature.IrisFeaturePositional; +import com.volmit.iris.engine.object.tile.TileData; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.mantle.MantleChunk; +import com.volmit.iris.util.matter.Matter; +import lombok.Data; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; + +@Data +public class MantleWriter implements IObjectPlacer +{ + private final EngineMantle engineMantle; + private final Mantle mantle; + private final KMap cachedChunks; + private final int radius; + private final int x; + private final int z; + + public MantleWriter(EngineMantle engineMantle, Mantle mantle, int x, int z, int radius) + { + this.engineMantle = engineMantle; + this.mantle = mantle; + this.cachedChunks = new KMap<>(); + this.radius = radius; + this.x = x; + this.z = z; + + for (int i = -radius; i <= radius; i++) { + for (int j = -radius; j <= radius; j++) { + cachedChunks.put(Cache.key(i + x, j + z), mantle.getChunk(i + x, j + z)); + } + } + } + + public void setData(int x, int y, int z, T t) + { + int cx = x >> 4; + int cz = z >> 4; + + if (y < 0 || y >= mantle.getWorldHeight()) { + return; + } + + if(cx >= this.x - radius && cx <= this.x + radius + && cz >= this.z - radius && cz <= this.z + radius) + { + MantleChunk chunk = cachedChunks.get(Cache.key(cx, cz)); + + if(chunk == null) + { + Iris.error("Mantle Writer Accessed " + cx + "," + cz + " and came up null (and yet within bounds!)"); + return; + } + + if(t instanceof IrisFeaturePositional) + { + chunk.addFeature((IrisFeaturePositional) t); + } + + else + { + Matter matter = chunk.getOrCreate(y >> 4); + matter.slice(matter.getClass(t)).set(x & 15, y & 15, z & 15, t); + } + } + + else + { + Iris.error("Mantle Writer[" + this.x + "," + this.z + ",R" + this.radius + "] Tried to access " + x + "," + y + "," + z + " (Chunk " + cx + "," + cz + ") which is OUT OF BOUNDS!"); + } + } + + @Override + public int getHighest(int x, int z, IrisData data) { + return engineMantle.getHighest(x, z, data); + } + + @Override + public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { + return engineMantle.getHighest(x, z, data, ignoreFluid); + } + + @Override + public void set(int x, int y, int z, BlockData d) { + setData(x, y, z, d); + } + + @Override + public BlockData get(int x, int y, int z) { + return getEngineMantle().get(x, y, z); + } + + @Override + public boolean isPreventingDecay() { + return getEngineMantle().isPreventingDecay(); + } + + @Override + public boolean isSolid(int x, int y, int z) { + return getEngineMantle().isSolid(x, y, z); + } + + @Override + public boolean isUnderwater(int x, int z) { + return getEngineMantle().isUnderwater(x, z); + } + + @Override + public int getFluidHeight() { + return getEngineMantle().getFluidHeight(); + } + + @Override + public boolean isDebugSmartBore() { + return getEngineMantle().isDebugSmartBore(); + } + + @Override + public void setTile(int xx, int yy, int zz, TileData tile) { + getEngineMantle().setTile(xx,yy,zz,tile); + } +} diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java index 098e76ca8..eb7f29da5 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleFeatureComponent.java @@ -21,6 +21,7 @@ package com.volmit.iris.engine.mantle.components; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.IrisMantleComponent; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; @@ -38,34 +39,34 @@ public class MantleFeatureComponent extends IrisMantleComponent { } @Override - public void generateLayer(int x, int z, Consumer post) { + public void generateLayer(MantleWriter writer, int x, int z, Consumer post) { RNG rng = new RNG(Cache.key(x, z) + seed()); int xxx = 8 + (x << 4); int zzz = 8 + (z << 4); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); - generateFeatures(rng, x, z, region, biome); + generateFeatures(writer, rng, x, z, region, biome); } @ChunkCoordinates - private void generateFeatures(RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) { + private void generateFeatures(MantleWriter writer, RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) { for (IrisFeaturePotential i : getFeatures()) { - placeZone(rng, cx, cz, i); + placeZone(writer, rng, cx, cz, i); } for (IrisFeaturePotential i : region.getFeatures()) { - placeZone(rng, cx, cz, i); + placeZone(writer, rng, cx, cz, i); } for (IrisFeaturePotential i : biome.getFeatures()) { - placeZone(rng, cx, cz, i); + placeZone(writer, rng, cx, cz, i); } } - private void placeZone(RNG rng, int cx, int cz, IrisFeaturePotential i) { + private void placeZone(MantleWriter writer, RNG rng, int cx, int cz, IrisFeaturePotential i) { int x = (cx << 4) + rng.nextInt(16); int z = (cz << 4) + rng.nextInt(16); - getMantle().set(x, 0, z, new IrisFeaturePositional(x, z, i.getZone())); + writer.setData(x, 0, z, new IrisFeaturePositional(x, z, i.getZone())); } private KList getFeatures() { diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index b93907542..2a946c845 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -18,12 +18,10 @@ package com.volmit.iris.engine.mantle.components; -import com.google.gson.Gson; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.IrisMantleComponent; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; @@ -50,17 +48,17 @@ public class MantleJigsawComponent extends IrisMantleComponent { } @Override - public void generateLayer(int x, int z, Consumer post) { + public void generateLayer(MantleWriter writer, int x, int z, Consumer post) { RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z)); int xxx = 8 + (x << 4); int zzz = 8 + (z << 4); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); - generateJigsaw(rng, x, z, biome, region, post); + generateJigsaw(writer, rng, x, z, biome, region, post); } @ChunkCoordinates - private void generateJigsaw(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) { + private void generateJigsaw(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) { boolean placed = false; if (getDimension().getStronghold() != null) { @@ -70,7 +68,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { for (Position2 pos : poss) { if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) { IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold()); - place(pos.toIris(), structure, rng, post); + place(writer, pos.toIris(), structure, rng, post); placed = true; } } @@ -82,7 +80,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { if (rng.nextInt(i.getRarity()) == 0) { IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); - place(position, structure, rng, post); + place(writer, position, structure, rng, post); placed = true; } } @@ -93,7 +91,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { if (rng.nextInt(i.getRarity()) == 0) { IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); - place(position, structure, rng, post); + place(writer, position, structure, rng, post); placed = true; } } @@ -104,22 +102,22 @@ public class MantleJigsawComponent extends IrisMantleComponent { if (rng.nextInt(i.getRarity()) == 0) { IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); - place(position, structure, rng, post); + place(writer, position, structure, rng, post); } } } } @BlockCoordinates - private void place(IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer post) { + private void place(MantleWriter writer, IrisPosition position, IrisJigsawStructure structure, RNG rng, Consumer post) { if (structure.getFeature() != null) { if (structure.getFeature().getBlockRadius() == 32) { structure.getFeature().setBlockRadius((double) structure.getMaxDimension() / 3); } - getMantle().set(position.getX(), 0, position.getZ(), + writer.setData(position.getX(), 0, position.getZ(), new IrisFeaturePositional(position.getX(), position.getZ(), structure.getFeature())); } - post.accept(() -> new PlannedStructure(structure, position, rng).place(getEngineMantle(), getMantle(), post)); + post.accept(() -> new PlannedStructure(structure, position, rng).place(writer, getMantle(), post)); } } diff --git a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java index b0eb8b7b2..13f32ca9b 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java +++ b/src/main/java/com/volmit/iris/engine/mantle/components/MantleObjectComponent.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.IrisMantleComponent; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.feature.IrisFeature; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; @@ -42,21 +43,21 @@ public class MantleObjectComponent extends IrisMantleComponent { } @Override - public void generateLayer(int x, int z, Consumer post) { + public void generateLayer(MantleWriter writer, int x, int z, Consumer post) { RNG rng = new RNG(Cache.key(x, z) + seed()); int xxx = 8 + (x << 4); int zzz = 8 + (z << 4); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); IrisBiome biome = getComplex().getTrueBiomeStreamNoFeatures().get(xxx, zzz); - placeObjects(rng, x, z, biome, region, post); + placeObjects(writer, rng, x, z, biome, region, post); } @ChunkCoordinates - private void placeObjects(RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) { + private void placeObjects(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region, Consumer post) { for (IrisObjectPlacement i : biome.getSurfaceObjects()) { if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) { try { - placeObject(rng, x << 4, z << 4, i, post); + placeObject(writer, rng, x << 4, z << 4, i, post); } catch (Throwable e) { Iris.reportError(e); Iris.error("Failed to place objects in the following biome: " + biome.getName()); @@ -70,7 +71,7 @@ public class MantleObjectComponent extends IrisMantleComponent { for (IrisObjectPlacement i : region.getSurfaceObjects()) { if (rng.chance(i.getChance() + rng.d(-0.005, 0.005)) && rng.chance(getComplex().getObjectChanceStream().get(x << 4, z << 4))) { try { - placeObject(rng, x << 4, z << 4, i, post); + placeObject(writer, rng, x << 4, z << 4, i, post); } catch (Throwable e) { Iris.reportError(e); Iris.error("Failed to place objects in the following region: " + region.getName()); @@ -83,7 +84,7 @@ public class MantleObjectComponent extends IrisMantleComponent { } @BlockCoordinates - private void placeObject(RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer post) { + private void placeObject(MantleWriter writer, RNG rng, int x, int z, IrisObjectPlacement objectPlacement, Consumer post) { for (int i = 0; i < objectPlacement.getDensity(); i++) { IrisObject v = objectPlacement.getScale().get(rng, objectPlacement.getObject(getComplex(), rng)); if (v == null) { @@ -94,8 +95,8 @@ public class MantleObjectComponent extends IrisMantleComponent { int id = rng.i(0, Integer.MAX_VALUE); Runnable r = () -> { - int h = v.place(xx, -1, zz, getEngineMantle(), objectPlacement, rng, - (b) -> getMantle().set(b.getX(), b.getY(), b.getZ(), + int h = v.place(xx, -1, zz, writer, objectPlacement, rng, + (b) -> writer.setData(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData()); if (objectPlacement.usesFeatures()) { @@ -108,12 +109,12 @@ public class MantleObjectComponent extends IrisMantleComponent { f.setInterpolationRadius(objectPlacement.getVacuumInterpolationRadius()); f.setInterpolator(objectPlacement.getVacuumInterpolationMethod()); f.setStrength(1D); - getMantle().set(xx, 0, zz, new IrisFeaturePositional(xx, zz, f)); + writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, f)); } for (IrisFeaturePotential j : objectPlacement.getAddFeatures()) { if (j.hasZone(rng, xx >> 4, zz >> 4)) { - getMantle().set(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone())); + writer.setData(xx, 0, zz, new IrisFeaturePositional(xx, zz, j.getZone())); } } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index 4def637ca..82bd57971 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -34,6 +34,7 @@ import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.RegionCoordinates; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.nbt.mca.MCAFile; import com.volmit.iris.util.nbt.mca.MCAUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.tag.CompoundTag; @@ -64,12 +65,11 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } @ChunkCoordinates - public void generateChunk(int x, int z) { + public void generateChunk(MCAFile file, int x, int z) { try { int ox = x << 4; int oz = z << 4; - com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(x, z); - + com.volmit.iris.util.nbt.mca.Chunk chunk = writer.getChunk(file, x, z); TerrainChunk tc = MCATerrainChunk.builder() .writer(writer).ox(ox).oz(oz).mcaChunk(chunk) .minHeight(world.getWorld().minHeight()).maxHeight(world.getWorld().maxHeight()) @@ -102,11 +102,12 @@ public class HeadlessGenerator implements PlatformChunkGenerator { @RegionCoordinates public void generateRegion(int x, int z, PregenListener listener) { BurstExecutor e = burst.burst(1024); + MCAFile f = writer.getMCA(x, x); PregenTask.iterateRegion(x, z, (ii, jj) -> e.queue(() -> { if (listener != null) { listener.onChunkGenerating(ii, jj); } - generateChunk(ii, jj); + generateChunk(f, ii, jj); if (listener != null) { listener.onChunkGenerated(ii, jj); } diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 38535fb5e..9c5dd7501 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -21,6 +21,8 @@ package com.volmit.iris.util.mantle; import com.google.common.collect.ImmutableList; import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.mantle.EngineMantle; +import com.volmit.iris.engine.mantle.MantleWriter; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.util.collection.KMap; @@ -101,6 +103,20 @@ public class Mantle { } } + /** + * Obtain a cached writer which only contains cached chunks. + * This avoids locking on regions when writing to lots of chunks + * @param x the x chunk + * @param z the z chunk + * @param radius the radius chunks + * @return the writer + */ + @ChunkCoordinates + public MantleWriter write(EngineMantle engineMantle, int x, int z, int radius) + { + return new MantleWriter(engineMantle, this, x, z, radius); + } + /** * Lower a flag if it is raised. If the flag was lowered (meaning it was previously raised), execute the runnable * @param x the chunk x @@ -911,4 +927,8 @@ public class Mantle { private static double lengthSq(double x, double z) { return (x * x) + (z * z); } + + public int getWorldHeight() { + return worldHeight; + } } diff --git a/src/main/java/com/volmit/iris/util/matter/Matter.java b/src/main/java/com/volmit/iris/util/matter/Matter.java index 621ced544..421c9fb3f 100644 --- a/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -27,6 +27,7 @@ import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.BlockPosition; import org.bukkit.World; import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_17_R1.block.data.type.CraftLeaves; import org.bukkit.entity.Entity; import java.io.*; @@ -189,7 +190,16 @@ public interface Matter { slice = (MatterSlice) createSlice(c, this); if (slice == null) { - Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName()); + try + { + throw new RuntimeException("Bad slice " + c.getCanonicalName()); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + return null; } diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java index 3d91dc202..04125982e 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java @@ -225,7 +225,7 @@ public class Chunk { * @param blockZ The z-coordinate of the block. * @return The biome id or -1 if the biomes are not correctly initialized. */ - public int getBiomeAt(int blockX, int blockY, int blockZ) { + public synchronized int getBiomeAt(int blockX, int blockY, int blockZ) { if (dataVersion < 2202) { if (biomes == null || biomes.length != 256) { return -1; @@ -244,7 +244,7 @@ public class Chunk { } @Deprecated - public void setBiomeAt(int blockX, int blockZ, int biomeID) { + public synchronized void setBiomeAt(int blockX, int blockZ, int biomeID) { if (dataVersion < 2202) { if (biomes == null || biomes.length != 256) { biomes = new int[256]; @@ -275,7 +275,7 @@ public class Chunk { * @param biomeID The biome id to be set. * When set to a negative number, Minecraft will replace it with the block column's default biome. */ - public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) { + public synchronized void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) { if (dataVersion < 2202) { if (biomes == null || biomes.length != 256) { biomes = new int[256]; diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java b/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java index 3c278c14e..a2b858f86 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/NBTWorld.java @@ -27,6 +27,7 @@ import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.M; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.nbt.tag.StringTag; +import com.volmit.iris.util.parallel.HyperLock; import com.volmit.iris.util.scheduling.IrisLock; import org.bukkit.NamespacedKey; import org.bukkit.block.Biome; @@ -43,8 +44,8 @@ public class NBTWorld { private static final BlockData AIR = B.get("AIR"); private static final Map blockDataCache = new KMap<>(); private static final Map biomeIds = computeBiomeIDs(); - private final IrisLock regionLock = new IrisLock("Region"); private final KMap loadedRegions; + private final HyperLock hyperLock = new HyperLock(); private final KMap lastUse; private final File worldFolder; private final ExecutorService saveQueue; @@ -62,13 +63,11 @@ public class NBTWorld { } public void close() { - regionLock.lock(); for (Long i : loadedRegions.k()) { queueSaveUnload(Cache.keyX(i), Cache.keyZ(i)); } - regionLock.unlock(); saveQueue.shutdown(); try { while (!saveQueue.awaitTermination(3, TimeUnit.SECONDS)) { @@ -80,13 +79,9 @@ public class NBTWorld { } public void flushNow() { - regionLock.lock(); - for (Long i : loadedRegions.k()) { doSaveUnload(Cache.keyX(i), Cache.keyZ(i)); } - - regionLock.unlock(); } public void queueSaveUnload(int x, int z) { @@ -103,8 +98,6 @@ public class NBTWorld { } public void save() { - regionLock.lock(); - boolean saving = true; for (Long i : loadedRegions.k()) { @@ -121,8 +114,6 @@ public class NBTWorld { } Iris.debug("Regions: " + C.GOLD + loadedRegions.size() + C.LIGHT_PURPLE); - - regionLock.unlock(); } public void queueSave() { @@ -131,10 +122,8 @@ public class NBTWorld { public synchronized void unloadRegion(int x, int z) { long key = Cache.key(x, z); - regionLock.lock(); loadedRegions.remove(key); lastUse.remove(key); - regionLock.unlock(); Iris.debug("Unloaded Region " + C.GOLD + x + " " + z); } @@ -249,6 +238,11 @@ public class NBTWorld { getChunkSection(x >> 4, y >> 4, z >> 4).setBlockStateAt(x & 15, y & 15, z & 15, getCompound(data), false); } + public int getBiomeId(Biome b) + { + return biomeIds.get(b); + } + public void setBiome(int x, int y, int z, Biome biome) { getChunk(x >> 4, z >> 4).setBiomeAt(x & 15, y, z & 15, biomeIds.get(biome)); } @@ -265,8 +259,12 @@ public class NBTWorld { return s; } - public synchronized Chunk getChunk(int x, int z) { - MCAFile mca = getMCA(x >> 5, z >> 5); + public Chunk getChunk(int x, int z) + { + return getChunk(getMCA(x >> 5, z >> 5), x, z); + } + + public Chunk getChunk(MCAFile mca, int x, int z) { Chunk c = mca.getChunk(x & 31, z & 31); if (c == null) { @@ -278,41 +276,40 @@ public class NBTWorld { } public long getIdleDuration(int x, int z) { - Long l = lastUse.get(Cache.key(x, z)); - - return l == null ? 0 : (M.ms() - l); + return hyperLock.withResult(x, z, () -> { + Long l = lastUse.get(Cache.key(x, z)); + return l == null ? 0 : (M.ms() - l); + }); } public MCAFile getMCA(int x, int z) { long key = Cache.key(x, z); - regionLock.lock(); - lastUse.put(key, M.ms()); - MCAFile mcaf = loadedRegions.get(key); - regionLock.unlock(); + return hyperLock.withResult(x, z, () -> { + lastUse.put(key, M.ms()); - if (mcaf == null) { - mcaf = new MCAFile(x, z); - regionLock.lock(); - loadedRegions.put(key, mcaf); - regionLock.unlock(); - } + MCAFile mcaf = loadedRegions.get(key); - return mcaf; + if (mcaf == null) { + mcaf = new MCAFile(x, z); + loadedRegions.put(key, mcaf); + } + + return mcaf; + }); } public MCAFile getMCAOrNull(int x, int z) { long key = Cache.key(x, z); - MCAFile ff = null; - regionLock.lock(); - if (loadedRegions.containsKey(key)) { - lastUse.put(key, M.ms()); - ff = loadedRegions.get(key); - } + return hyperLock.withResult(x, z, () -> { + if (loadedRegions.containsKey(key)) { + lastUse.put(key, M.ms()); + return loadedRegions.get(key); + } - regionLock.unlock(); - return ff; + return null; + }); } public int size() { diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/Section.java b/src/main/java/com/volmit/iris/util/nbt/mca/Section.java index 901de03af..89ce29962 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/Section.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/Section.java @@ -24,6 +24,7 @@ import com.volmit.iris.util.nbt.tag.ByteArrayTag; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.nbt.tag.ListTag; import com.volmit.iris.util.nbt.tag.LongArrayTag; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import java.util.ArrayList; import java.util.HashMap; @@ -170,7 +171,7 @@ public class Section { * This option should only be used moderately to avoid unnecessary recalculation of the palette indices. * Recalculating the Palette should only be executed once right before saving the Section to file. */ - public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) { + public synchronized void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) { int paletteSizeBefore = palette.size(); int paletteIndex = addToPalette(state); //power of 2 --> bits must increase, but only if the palette size changed @@ -223,7 +224,7 @@ public class Section { * @param paletteIndex The block state to be set (index of block data in the palette). * @param blockStates The block states to be updated. */ - public void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) { + public synchronized void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) { int bits = blockStates.length() >> 6; if (dataVersion < 2527) { @@ -253,7 +254,7 @@ public class Section { return palette; } - int addToPalette(CompoundTag data) { + synchronized int addToPalette(CompoundTag data) { PaletteIndex index; if ((index = getValueIndexedPalette(data)) != null) { return index.index; @@ -283,14 +284,14 @@ public class Section { * This should only be used moderately to avoid unnecessary recalculation of the palette indices. * Recalculating the Palette should only be executed once right before saving the Section to file. */ - public void cleanupPaletteAndBlockStates() { + public synchronized void cleanupPaletteAndBlockStates() { Map oldToNewMapping = cleanupPalette(); adjustBlockStateBits(oldToNewMapping, blockStates); } - private Map cleanupPalette() { + private synchronized Map cleanupPalette() { //create index - palette mapping - Map allIndices = new HashMap<>(); + Map allIndices = new Int2IntOpenHashMap(); for (int i = 0; i < 4096; i++) { int paletteIndex = getPaletteIndex(i); allIndices.put(paletteIndex, paletteIndex); @@ -314,7 +315,7 @@ public class Section { return allIndices; } - void adjustBlockStateBits(Map oldToNewMapping, AtomicLongArray blockStates) { + synchronized void adjustBlockStateBits(Map oldToNewMapping, AtomicLongArray blockStates) { //increases or decreases the amount of bits used per BlockState //based on the size of the palette. oldToNewMapping can be used to update indices //if the palette had been cleaned up before using MCAFile#cleanupPalette(). @@ -376,7 +377,7 @@ public class Section { * @throws NullPointerException If blockStates is null * @throws IllegalArgumentException When blockStates' length is < 256 or > 4096 and is not a multiple of 64 */ - public void setBlockStates(AtomicLongArray blockStates) { + public synchronized void setBlockStates(AtomicLongArray blockStates) { if (blockStates == null) { throw new NullPointerException("BlockStates cannot be null"); } else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) { diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 6b21ddb21..ce21c64f7 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -19,6 +19,7 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.M; @@ -50,7 +51,7 @@ public class MultiBurst { private synchronized ExecutorService getService() { last.set(M.ms()); if (service == null || service.isShutdown()) { - service = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), + service = new ForkJoinPool(IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()), new ForkJoinPool.ForkJoinWorkerThreadFactory() { int m = 0; From 56e13641dfff38db7d6ddf7c60bbc2466b6e6c01 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Mon, 23 Aug 2021 03:15:17 -0400 Subject: [PATCH 39/39] V+ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1b677aafb..753f55c8a 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.7.7' +version '1.7.8' def apiVersion = '1.17' def name = getRootProject().getName() // See settings.gradle def main = 'com.volmit.iris.Iris'