From da1895125a1f23c57d9390c2ba84191e0c2be8b3 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 17 Jul 2021 00:29:33 -0400 Subject: [PATCH] Island terrain mode (experimental) --- .../com/volmit/iris/engine/IrisComplex.java | 25 ++++-- .../iris/engine/IrisEngineFramework.java | 19 ++++- .../actuator/IrisTerrainIslandActuator.java | 82 +++++++++++++++++++ ...or.java => IrisTerrainNormalActuator.java} | 5 +- .../iris/engine/object/IrisDimension.java | 5 ++ .../engine/object/IrisGeneratorStyle.java | 6 -- .../iris/engine/object/IrisStyledRange.java | 63 ++++++++++++++ .../iris/engine/object/IrisTerrainIsland.java | 45 ++++++++++ .../iris/engine/object/IrisTerrainMode.java | 24 ++++++ 9 files changed, 256 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java rename src/main/java/com/volmit/iris/engine/actuator/{IrisTerrainActuator.java => IrisTerrainNormalActuator.java} (97%) create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisStyledRange.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTerrainIsland.java create mode 100644 src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java diff --git a/src/main/java/com/volmit/iris/engine/IrisComplex.java b/src/main/java/com/volmit/iris/engine/IrisComplex.java index 8484cf73d..3659e6e3f 100644 --- a/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -21,8 +21,7 @@ package com.volmit.iris.engine; import com.google.common.util.concurrent.AtomicDouble; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisDataManager; -import com.volmit.iris.core.IrisSettings; -import com.volmit.iris.engine.actuator.IrisTerrainActuator; +import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.data.DataProvider; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.modifier.IrisCaveModifier; @@ -50,6 +49,11 @@ public class IrisComplex implements DataProvider { private KList generators; private static final BlockData AIR = Material.AIR.createBlockData(); private ProceduralStream regionStream; + private ProceduralStream regionStyleStream; + private ProceduralStream regionIdentityStream; + private ProceduralStream islandStream; + private ProceduralStream islandHeightStream; + private ProceduralStream islandDepthStream; private ProceduralStream bridgeStream; private ProceduralStream landBiomeStream; private ProceduralStream caveBiomeStream; @@ -126,11 +130,18 @@ public class IrisComplex implements DataProvider { .select(engine.getDimension().getRockPalette().getBlockData(data)); fluidStream = engine.getDimension().getFluidPalette().getLayerGenerator(rng.nextParallelRNG(78), data).stream() .select(engine.getDimension().getFluidPalette().getBlockData(data)); + regionStyleStream = engine.getDimension().getRegionStyle().create(rng.nextParallelRNG(883)).stream() + .zoom(engine.getDimension().getRegionZoom()); + regionIdentityStream = regionStyleStream.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE); + islandStream = regionStyleStream + .seededChance(rng.nextParallelRNG(29349), 23968888888L, + engine.getDimension().getIslandMode().getIslandChance()); + islandHeightStream = regionIdentityStream.style(rng.nextParallelRNG(330466), engine.getDimension().getIslandMode().getHeight()); + islandDepthStream = engine.getDimension().getIslandMode().getIslandDepth().stream(rng.nextParallelRNG(-39578888)); regionStream = focusRegion != null ? ProceduralStream.of((x, z) -> focusRegion, Interpolated.of(a -> 0D, a -> focusRegion)) - : engine.getDimension().getRegionStyle().create(rng.nextParallelRNG(883)).stream() - .zoom(engine.getDimension().getRegionZoom()) + : regionStyleStream .selectRarity(engine.getDimension().getRegions(), (i) -> data.getRegionLoader().load(i)) .convertCached((s) -> data.getRegionLoader().load(s)).cache2D(cacheSize); caveBiomeStream = regionStream.convert((r) @@ -220,11 +231,11 @@ public class IrisComplex implements DataProvider { int heightf = (int) Math.round(getHeightStream().get(rx, rz)); int m = heightf; - if (engine.getDimension().isCarving()) { - if (engine.getDimension().isCarved(rx, m, rz, ((IrisTerrainActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + if (engine.getDimension().isCarving() && engine.getDimension().getTerrainMode().equals(IrisTerrainMode.NORMAL)) { + if (engine.getDimension().isCarved(rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { m--; - while (engine.getDimension().isCarved(rx, m, rz, ((IrisTerrainActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { + while (engine.getDimension().isCarved(rx, m, rz, ((IrisTerrainNormalActuator) engine.getFramework().getTerrainActuator()).getRng(), heightf)) { m--; } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java index 48e516641..1a8078c52 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngineFramework.java @@ -22,7 +22,8 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.actuator.IrisBiomeActuator; import com.volmit.iris.engine.actuator.IrisDecorantActuator; -import com.volmit.iris.engine.actuator.IrisTerrainActuator; +import com.volmit.iris.engine.actuator.IrisTerrainIslandActuator; +import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator; import com.volmit.iris.engine.framework.*; import com.volmit.iris.engine.modifier.IrisCaveModifier; import com.volmit.iris.engine.modifier.IrisDepositModifier; @@ -47,7 +48,10 @@ public class IrisEngineFramework implements EngineFramework { final EngineParallaxManager engineParallax; @Getter - private final EngineActuator terrainActuator; + private final EngineActuator terrainNormalActuator; + + @Getter + private final EngineActuator terrainIslandActuator; @Getter private final EngineActuator decorantActuator; @@ -74,7 +78,8 @@ public class IrisEngineFramework implements EngineFramework { this.engine = engine; this.complex = new IrisComplex(getEngine()); this.engineParallax = new IrisEngineParallax(getEngine()); - this.terrainActuator = new IrisTerrainActuator(getEngine()); + this.terrainNormalActuator = new IrisTerrainNormalActuator(getEngine()); + this.terrainIslandActuator = new IrisTerrainIslandActuator(getEngine()); this.decorantActuator = new IrisDecorantActuator(getEngine()); this.biomeActuator = new IrisBiomeActuator(getEngine()); this.depositModifier = new IrisDepositModifier(getEngine()); @@ -110,6 +115,14 @@ public class IrisEngineFramework implements EngineFramework { cleaning.lazySet(false); } + @Override + public EngineActuator getTerrainActuator() { + return switch (getEngine().getDimension().getTerrainMode()){ + case NORMAL -> getTerrainNormalActuator(); + case ISLANDS -> getTerrainIslandActuator(); + }; + } + @Override public void close() { getEngineParallax().close(); diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java new file mode 100644 index 000000000..a22ac4ae1 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainIslandActuator.java @@ -0,0 +1,82 @@ +/* + * 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.Iris; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.EngineAssignedActuator; +import com.volmit.iris.engine.hunk.Hunk; +import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.math.M; +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; + private final boolean hasUnder; + @Getter + private int lastBedrock = -1; + + public IrisTerrainIslandActuator(Engine engine) { + super(engine, "TerrainIsland"); + rng = new RNG(engine.getWorld().getSeed()); + carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); + hasUnder = getDimension().getUndercarriage() != null && !getDimension().getUndercarriage().getGenerator().isFlat(); + } + + @Override + public void onActuate(int x, int z, Hunk h) { + PrecisionStopwatch p = PrecisionStopwatch.start(); + int i, zf, depth, surface, realX, realZ; + IrisBiome biome; + KList blocks, fblocks; + + 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)) + { + surface = getComplex().getIslandHeightStream().get(realX, realZ).intValue(); + depth = getComplex().getIslandDepthStream().get(realX, realZ).intValue(); + + for(i = surface - depth; i < surface; i++) + { + h.set(xf, i, zf, BEDROCK); + } + } + } + } + + getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); + } +} diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java similarity index 97% rename from src/main/java/com/volmit/iris/engine/actuator/IrisTerrainActuator.java rename to src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index c33edd429..cce03edc3 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -29,7 +29,7 @@ import lombok.Getter; import org.bukkit.Material; import org.bukkit.block.data.BlockData; -public class IrisTerrainActuator extends EngineAssignedActuator { +public class IrisTerrainNormalActuator extends EngineAssignedActuator { private static final BlockData AIR = Material.AIR.createBlockData(); private static final BlockData BEDROCK = Material.BEDROCK.createBlockData(); private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData(); @@ -40,7 +40,7 @@ public class IrisTerrainActuator extends EngineAssignedActuator { @Getter private int lastBedrock = -1; - public IrisTerrainActuator(Engine engine) { + public IrisTerrainNormalActuator(Engine engine) { super(engine, "Terrain"); rng = new RNG(engine.getWorld().getSeed()); carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); @@ -54,6 +54,7 @@ public class IrisTerrainActuator extends EngineAssignedActuator { IrisBiome biome; KList blocks, fblocks; + for (int xf = 0; xf < h.getWidth(); xf++) { for (zf = 0; zf < h.getDepth(); zf++) { realX = (int) modX(xf + x); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index a829382b0..9119c39c9 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -290,6 +290,11 @@ 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 schematics in biomes") private boolean placeObjects = true; diff --git a/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java index 36ee3473e..0cede5423 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java @@ -38,29 +38,23 @@ import lombok.experimental.Accessors; public class IrisGeneratorStyle { @Required - @Desc("The chance is 1 in CHANCE per interval") private NoiseStyle style = NoiseStyle.IRIS; - @MinNumber(0.00001) @Desc("The zoom of this style") private double zoom = 1; - @MinNumber(0.00001) @Desc("The Output multiplier. Only used if parent is fracture.") private double multiplier = 1; - @Desc("If set to true, each dimension will be fractured with a different order of input coordinates. This is usually 2 or 3 times slower than normal.") private boolean maxFractureAccuracy = false; - @Desc("Apply a generator to the coordinate field fed into this parent generator. I.e. Distort your generator with another generator.") private IrisGeneratorStyle fracture = null; - @MinNumber(0.01562) @MaxNumber(64) @Desc("The exponent") diff --git a/src/main/java/com/volmit/iris/engine/object/IrisStyledRange.java b/src/main/java/com/volmit/iris/engine/object/IrisStyledRange.java new file mode 100644 index 000000000..3bbffc4da --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisStyledRange.java @@ -0,0 +1,63 @@ +/* + * 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; + +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.stream.ProceduralStream; +import com.volmit.iris.engine.stream.interpolation.Interpolated; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.math.RNG; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Represents a range styled with a custom generator") +@Data +public class IrisStyledRange { + + @Desc("The minimum value") + private double min = 16; + + @Desc("The maximum value") + private double max = 32; + + @Desc("The style to pick the range") + private IrisGeneratorStyle style = new IrisGeneratorStyle(NoiseStyle.STATIC); + + public double get(RNG rng, double x, double z) { + if (min == max) { + return min; + } + + if(style.isFlat()) + { + return M.lerp(min, max, 0.5); + } + + return style.create(rng).fitDouble(min, max, x, z); + } + + public ProceduralStream stream(RNG rng) { + return ProceduralStream.of((x, z) -> get(rng, x, z), Interpolated.DOUBLE); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTerrainIsland.java b/src/main/java/com/volmit/iris/engine/object/IrisTerrainIsland.java new file mode 100644 index 000000000..648651ae1 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTerrainIsland.java @@ -0,0 +1,45 @@ +/* + * 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; + +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 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; +} diff --git a/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java b/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java new file mode 100644 index 000000000..fed827bee --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/IrisTerrainMode.java @@ -0,0 +1,24 @@ +/* + * 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; + +public enum IrisTerrainMode { + NORMAL, + ISLANDS +}