mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-03 06:16:19 +00:00
f
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,6 @@ import art.arcane.iris.engine.object.*;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.volmlib.util.collection.KMap;
|
||||
import art.arcane.volmlib.util.collection.KSet;
|
||||
import art.arcane.volmlib.util.io.IO;
|
||||
import art.arcane.iris.util.common.format.C;
|
||||
import art.arcane.iris.util.common.misc.ServerProperties;
|
||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||
@@ -42,8 +41,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -147,42 +144,24 @@ public class ServerConfigurator {
|
||||
|
||||
File source = Iris.instance.getDataFolder("datapacks");
|
||||
source.mkdirs();
|
||||
File[] datapacks = source.listFiles();
|
||||
if (datapacks == null || datapacks.length == 0) {
|
||||
return;
|
||||
ExternalDataPackPipeline.syncPinnedDatapacks(source);
|
||||
int removedLegacyCopies = ExternalDataPackPipeline.removeLegacyWorldDatapackCopies(source, folders);
|
||||
ExternalDataPackPipeline.ImportSummary summary = ExternalDataPackPipeline.importDatapackStructures(source);
|
||||
if (removedLegacyCopies > 0) {
|
||||
Iris.info("Removed " + removedLegacyCopies + " legacy external datapack world copies.");
|
||||
}
|
||||
|
||||
int copied = 0;
|
||||
for (File targetFolder : folders) {
|
||||
targetFolder.mkdirs();
|
||||
for (File entry : datapacks) {
|
||||
if (entry == null || !entry.exists() || entry.getName().startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
File output = new File(targetFolder, entry.getName());
|
||||
try {
|
||||
if (entry.isDirectory()) {
|
||||
IO.copyDirectory(entry.toPath(), output.toPath());
|
||||
} else if (entry.isFile()) {
|
||||
File parent = output.getParentFile();
|
||||
if (parent != null) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
Files.copy(entry.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
copied++;
|
||||
} catch (Throwable e) {
|
||||
Iris.warn("Failed to install datapack \"" + entry.getName() + "\" into \"" + targetFolder.getPath() + "\"");
|
||||
Iris.reportError(e);
|
||||
}
|
||||
}
|
||||
if (summary.getSources() > 0) {
|
||||
Iris.info("External datapack structure import: sources=" + summary.getSources()
|
||||
+ ", cached=" + summary.getCachedSources()
|
||||
+ ", scanned=" + summary.getNbtScanned()
|
||||
+ ", converted=" + summary.getConverted()
|
||||
+ ", failed=" + summary.getFailed()
|
||||
+ ", skipped=" + summary.getSkipped()
|
||||
+ ", entitiesIgnored=" + summary.getEntitiesIgnored()
|
||||
+ ", blockEntities=" + summary.getBlockEntities());
|
||||
}
|
||||
|
||||
if (copied > 0) {
|
||||
Iris.info("Installed " + copied + " external datapack copy operation" + (copied == 1 ? "" : "s") + " from " + source.getPath());
|
||||
if (summary.getSources() > 0 || summary.getConverted() > 0) {
|
||||
Iris.info("External datapack world install is disabled; only structure template import is applied.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
}
|
||||
}
|
||||
|
||||
return getCaveBiome(x, z);
|
||||
return getCaveBiome(x, y, z);
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
@@ -236,6 +236,28 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
return getComplex().getCaveBiomeStream().get(x, z);
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
default IrisBiome getCaveBiome(int x, int y, int z) {
|
||||
IrisBiome caveBiome = getCaveBiome(x, z);
|
||||
IrisBiome surfaceBiome = getSurfaceBiome(x, z);
|
||||
if (caveBiome == null) {
|
||||
return surfaceBiome;
|
||||
}
|
||||
|
||||
int surfaceY = getComplex().getHeightStream().get(x, z).intValue();
|
||||
int depthBelowSurface = surfaceY - y;
|
||||
if (depthBelowSurface <= 0) {
|
||||
return surfaceBiome;
|
||||
}
|
||||
|
||||
int minDepth = Math.max(0, caveBiome.getCaveMinDepthBelowSurface());
|
||||
if (depthBelowSurface < minDepth) {
|
||||
return surfaceBiome;
|
||||
}
|
||||
|
||||
return caveBiome;
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
default IrisBiome getSurfaceBiome(int x, int z) {
|
||||
return getComplex().getTrueBiomeStream().get(x, z);
|
||||
@@ -514,7 +536,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
|
||||
IrisRegion region = getComplex().getRegionStream().get(rx, rz);
|
||||
IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz);
|
||||
IrisBiome biomeUnder = ry < he ? getComplex().getCaveBiomeStream().get(rx, rz) : biomeSurface;
|
||||
IrisBiome biomeUnder = ry < he ? getCaveBiome(rx, ry, rz) : biomeSurface;
|
||||
|
||||
double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
|
||||
boolean fallback = tables.isEmpty();
|
||||
@@ -796,7 +818,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
|
||||
default IrisBiome getBiome(int x, int y, int z) {
|
||||
if (y <= getHeight(x, z) - 2) {
|
||||
return getCaveBiome(x, z);
|
||||
return getCaveBiome(x, y, z);
|
||||
}
|
||||
|
||||
return getSurfaceBiome(x, z);
|
||||
|
||||
@@ -98,35 +98,132 @@ public class IrisCaveCarver3D {
|
||||
|
||||
int x0 = chunkX << 4;
|
||||
int z0 = chunkZ << 4;
|
||||
int[] columnSurface = new int[256];
|
||||
int[] columnMaxY = new int[256];
|
||||
int[] surfaceBreakFloorY = new int[256];
|
||||
boolean[] surfaceBreakColumn = new boolean[256];
|
||||
double[] columnThreshold = new double[256];
|
||||
|
||||
for (int lx = 0; lx < 16; lx++) {
|
||||
int x = x0 + lx;
|
||||
for (int lz = 0; lz < 16; lz++) {
|
||||
int z = z0 + lz;
|
||||
int index = (lx << 4) | lz;
|
||||
int columnSurfaceY = engine.getHeight(x, z);
|
||||
int clearanceTopY = Math.min(maxY, Math.max(minY, columnSurfaceY - surfaceClearance));
|
||||
boolean breakColumn = allowSurfaceBreak
|
||||
&& signed(surfaceBreakDensity.noise(x, z)) >= surfaceBreakNoiseThreshold;
|
||||
int columnTopY = breakColumn
|
||||
? Math.min(maxY, Math.max(minY, columnSurfaceY))
|
||||
: clearanceTopY;
|
||||
|
||||
columnSurface[index] = columnSurfaceY;
|
||||
columnMaxY[index] = columnTopY;
|
||||
surfaceBreakFloorY[index] = Math.max(minY, columnSurfaceY - surfaceBreakDepth);
|
||||
surfaceBreakColumn[index] = breakColumn;
|
||||
columnThreshold[index] = profile.getDensityThreshold().get(thresholdRng, x, z, data) - profile.getThresholdBias();
|
||||
}
|
||||
}
|
||||
|
||||
int carved = carvePass(
|
||||
writer,
|
||||
x0,
|
||||
z0,
|
||||
minY,
|
||||
maxY,
|
||||
sampleStep,
|
||||
surfaceBreakThresholdBoost,
|
||||
waterMinDepthBelowSurface,
|
||||
waterRequiresFloor,
|
||||
columnSurface,
|
||||
columnMaxY,
|
||||
surfaceBreakFloorY,
|
||||
surfaceBreakColumn,
|
||||
columnThreshold,
|
||||
0D,
|
||||
false
|
||||
);
|
||||
|
||||
int minCarveCells = Math.max(0, profile.getMinCarveCells());
|
||||
double recoveryThresholdBoost = Math.max(0, profile.getRecoveryThresholdBoost());
|
||||
if (carved < minCarveCells && recoveryThresholdBoost > 0D) {
|
||||
carved += carvePass(
|
||||
writer,
|
||||
x0,
|
||||
z0,
|
||||
minY,
|
||||
maxY,
|
||||
sampleStep,
|
||||
surfaceBreakThresholdBoost,
|
||||
waterMinDepthBelowSurface,
|
||||
waterRequiresFloor,
|
||||
columnSurface,
|
||||
columnMaxY,
|
||||
surfaceBreakFloorY,
|
||||
surfaceBreakColumn,
|
||||
columnThreshold,
|
||||
recoveryThresholdBoost,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return carved;
|
||||
}
|
||||
|
||||
private int carvePass(
|
||||
MantleWriter writer,
|
||||
int x0,
|
||||
int z0,
|
||||
int minY,
|
||||
int maxY,
|
||||
int sampleStep,
|
||||
double surfaceBreakThresholdBoost,
|
||||
int waterMinDepthBelowSurface,
|
||||
boolean waterRequiresFloor,
|
||||
int[] columnSurface,
|
||||
int[] columnMaxY,
|
||||
int[] surfaceBreakFloorY,
|
||||
boolean[] surfaceBreakColumn,
|
||||
double[] columnThreshold,
|
||||
double thresholdBoost,
|
||||
boolean skipExistingCarved
|
||||
) {
|
||||
int carved = 0;
|
||||
|
||||
for (int x = x0; x < x0 + 16; x++) {
|
||||
for (int z = z0; z < z0 + 16; z++) {
|
||||
double threshold = profile.getDensityThreshold().get(thresholdRng, x, z, data) - profile.getThresholdBias();
|
||||
int columnSurface = engine.getHeight(x, z);
|
||||
int clearanceTopY = Math.min(maxY, Math.max(minY, columnSurface - surfaceClearance));
|
||||
boolean surfaceBreakColumn = allowSurfaceBreak
|
||||
&& signed(surfaceBreakDensity.noise(x, z)) >= surfaceBreakNoiseThreshold;
|
||||
int columnMaxY = surfaceBreakColumn
|
||||
? Math.min(maxY, Math.max(minY, columnSurface))
|
||||
: clearanceTopY;
|
||||
int surfaceBreakFloorY = Math.max(minY, columnSurface - surfaceBreakDepth);
|
||||
if (columnMaxY < minY) {
|
||||
for (int lx = 0; lx < 16; lx++) {
|
||||
int x = x0 + lx;
|
||||
for (int lz = 0; lz < 16; lz++) {
|
||||
int z = z0 + lz;
|
||||
int index = (lx << 4) | lz;
|
||||
int columnTopY = columnMaxY[index];
|
||||
if (columnTopY < minY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int y = minY; y <= columnMaxY; y += sampleStep) {
|
||||
boolean breakColumn = surfaceBreakColumn[index];
|
||||
int breakFloorY = surfaceBreakFloorY[index];
|
||||
int surfaceY = columnSurface[index];
|
||||
double threshold = columnThreshold[index] + thresholdBoost;
|
||||
|
||||
for (int y = minY; y <= columnTopY; y += sampleStep) {
|
||||
double localThreshold = threshold;
|
||||
if (surfaceBreakColumn && y >= surfaceBreakFloorY) {
|
||||
if (breakColumn && y >= breakFloorY) {
|
||||
localThreshold += surfaceBreakThresholdBoost;
|
||||
}
|
||||
|
||||
if (sampleDensity(x, y, z) <= localThreshold) {
|
||||
int carveMaxY = Math.min(columnMaxY, y + sampleStep - 1);
|
||||
for (int yy = y; yy <= carveMaxY; yy++) {
|
||||
writer.setData(x, yy, z, resolveMatter(x, yy, z, localThreshold, waterMinDepthBelowSurface, waterRequiresFloor));
|
||||
carved++;
|
||||
localThreshold = applyVerticalEdgeFade(localThreshold, y, minY, maxY);
|
||||
if (sampleDensity(x, y, z) > localThreshold) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int carveMaxY = Math.min(columnTopY, y + sampleStep - 1);
|
||||
for (int yy = y; yy <= carveMaxY; yy++) {
|
||||
if (skipExistingCarved && writer.isCarved(x, yy, z)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
writer.setData(x, yy, z, resolveMatter(x, yy, z, surfaceY, localThreshold, waterMinDepthBelowSurface, waterRequiresFloor));
|
||||
carved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,6 +232,25 @@ public class IrisCaveCarver3D {
|
||||
return carved;
|
||||
}
|
||||
|
||||
private double applyVerticalEdgeFade(double threshold, int y, int minY, int maxY) {
|
||||
int fadeRange = Math.max(0, profile.getVerticalEdgeFade());
|
||||
if (fadeRange <= 0 || maxY <= minY) {
|
||||
return threshold;
|
||||
}
|
||||
|
||||
int floorDistance = y - minY;
|
||||
int ceilingDistance = maxY - y;
|
||||
int edgeDistance = Math.min(floorDistance, ceilingDistance);
|
||||
if (edgeDistance >= fadeRange) {
|
||||
return threshold;
|
||||
}
|
||||
|
||||
double t = Math.max(0D, Math.min(1D, edgeDistance / (double) fadeRange));
|
||||
double smooth = t * t * (3D - (2D * t));
|
||||
double fadeStrength = Math.max(0D, profile.getVerticalEdgeFadeStrength());
|
||||
return threshold - ((1D - smooth) * fadeStrength);
|
||||
}
|
||||
|
||||
private double sampleDensity(int x, int y, int z) {
|
||||
double warpedX = x;
|
||||
double warpedY = y;
|
||||
@@ -142,9 +258,11 @@ public class IrisCaveCarver3D {
|
||||
double warpStrength = profile.getWarpStrength();
|
||||
|
||||
if (warpStrength > 0) {
|
||||
double offsetX = signed(warpDensity.noise(x, y, z)) * warpStrength;
|
||||
double offsetY = signed(warpDensity.noise(y, z, x)) * warpStrength;
|
||||
double offsetZ = signed(warpDensity.noise(z, x, y)) * warpStrength;
|
||||
double warpA = signed(warpDensity.noise(x, y, z));
|
||||
double warpB = signed(warpDensity.noise(x + 31.37D, y - 17.21D, z + 23.91D));
|
||||
double offsetX = warpA * warpStrength;
|
||||
double offsetY = warpB * warpStrength;
|
||||
double offsetZ = (warpA - warpB) * 0.5D * warpStrength;
|
||||
warpedX += offsetX;
|
||||
warpedY += offsetY;
|
||||
warpedZ += offsetZ;
|
||||
@@ -169,7 +287,7 @@ public class IrisCaveCarver3D {
|
||||
return density / normalization;
|
||||
}
|
||||
|
||||
private MatterCavern resolveMatter(int x, int y, int z, double localThreshold, int waterMinDepthBelowSurface, boolean waterRequiresFloor) {
|
||||
private MatterCavern resolveMatter(int x, int y, int z, int surfaceY, double localThreshold, int waterMinDepthBelowSurface, boolean waterRequiresFloor) {
|
||||
int lavaHeight = engine.getDimension().getCaveLavaHeight();
|
||||
int fluidHeight = engine.getDimension().getFluidHeight();
|
||||
|
||||
@@ -178,7 +296,6 @@ public class IrisCaveCarver3D {
|
||||
}
|
||||
|
||||
if (profile.isAllowWater() && y <= fluidHeight) {
|
||||
int surfaceY = engine.getHeight(x, z);
|
||||
if (surfaceY - y < waterMinDepthBelowSurface) {
|
||||
return carveAir;
|
||||
}
|
||||
@@ -207,7 +324,6 @@ public class IrisCaveCarver3D {
|
||||
private boolean hasAquiferCupSupport(int x, int y, int z, double threshold) {
|
||||
int floorY = Math.max(0, y - 1);
|
||||
int deepFloorY = Math.max(0, y - 2);
|
||||
int aboveY = Math.min(engine.getHeight() - 1, y + 1);
|
||||
if (!isDensitySolid(x, floorY, z, threshold)) {
|
||||
return false;
|
||||
}
|
||||
@@ -229,11 +345,8 @@ public class IrisCaveCarver3D {
|
||||
if (isDensitySolid(x, y, z - 1, threshold)) {
|
||||
support++;
|
||||
}
|
||||
if (isDensitySolid(x, aboveY, z, threshold)) {
|
||||
support++;
|
||||
}
|
||||
|
||||
return support >= 4;
|
||||
return support >= 3;
|
||||
}
|
||||
|
||||
private boolean isDensitySolid(int x, int y, int z, double threshold) {
|
||||
|
||||
@@ -50,23 +50,47 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
||||
int xxx = 8 + (x << 4);
|
||||
int zzz = 8 + (z << 4);
|
||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
|
||||
carve(writer, rng, x, z, region, biome);
|
||||
IrisBiome surfaceBiome = getComplex().getTrueBiomeStream().get(xxx, zzz);
|
||||
IrisCaveProfile caveBiomeProfile = resolveDominantCaveBiomeProfile(x, z);
|
||||
carve(writer, rng, x, z, region, surfaceBiome, caveBiomeProfile);
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
private void carve(MantleWriter writer, RNG rng, int cx, int cz, IrisRegion region, IrisBiome biome) {
|
||||
private void carve(MantleWriter writer, RNG rng, int cx, int cz, IrisRegion region, IrisBiome surfaceBiome, IrisCaveProfile caveBiomeProfile) {
|
||||
IrisCaveProfile dimensionProfile = getDimension().getCaveProfile();
|
||||
IrisCaveProfile biomeProfile = biome.getCaveProfile();
|
||||
IrisCaveProfile surfaceBiomeProfile = surfaceBiome.getCaveProfile();
|
||||
IrisCaveProfile regionProfile = region.getCaveProfile();
|
||||
IrisCaveProfile activeProfile = resolveActiveProfile(dimensionProfile, regionProfile, biomeProfile);
|
||||
IrisCaveProfile activeProfile = resolveActiveProfile(dimensionProfile, regionProfile, surfaceBiomeProfile, caveBiomeProfile);
|
||||
if (isProfileEnabled(activeProfile)) {
|
||||
carveProfile(activeProfile, writer, cx, cz);
|
||||
return;
|
||||
int carved = carveProfile(activeProfile, writer, cx, cz);
|
||||
if (carved > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeProfile != regionProfile && isProfileEnabled(regionProfile)) {
|
||||
carved = carveProfile(regionProfile, writer, cx, cz);
|
||||
if (carved > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeProfile != surfaceBiomeProfile && isProfileEnabled(surfaceBiomeProfile)) {
|
||||
carved = carveProfile(surfaceBiomeProfile, writer, cx, cz);
|
||||
if (carved > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeProfile != dimensionProfile && isProfileEnabled(dimensionProfile)) {
|
||||
carved = carveProfile(dimensionProfile, writer, cx, cz);
|
||||
if (carved > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
carve(getDimension().getCarving(), writer, nextCarveRng(rng, cx, cz), cx, cz);
|
||||
carve(biome.getCarving(), writer, nextCarveRng(rng, cx, cz), cx, cz);
|
||||
carve(surfaceBiome.getCarving(), writer, nextCarveRng(rng, cx, cz), cx, cz);
|
||||
carve(region.getCarving(), writer, nextCarveRng(rng, cx, cz), cx, cz);
|
||||
}
|
||||
|
||||
@@ -80,13 +104,13 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
private void carveProfile(IrisCaveProfile profile, MantleWriter writer, int cx, int cz) {
|
||||
private int carveProfile(IrisCaveProfile profile, MantleWriter writer, int cx, int cz) {
|
||||
if (!isProfileEnabled(profile)) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IrisCaveCarver3D carver = getCarver(profile);
|
||||
carver.carve(writer, cx, cz);
|
||||
return carver.carve(writer, cx, cz);
|
||||
}
|
||||
|
||||
private IrisCaveCarver3D getCarver(IrisCaveProfile profile) {
|
||||
@@ -106,9 +130,59 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
||||
return profile != null && profile.isEnabled();
|
||||
}
|
||||
|
||||
private IrisCaveProfile resolveActiveProfile(IrisCaveProfile dimensionProfile, IrisCaveProfile regionProfile, IrisCaveProfile biomeProfile) {
|
||||
if (isProfileEnabled(biomeProfile)) {
|
||||
return biomeProfile;
|
||||
@ChunkCoordinates
|
||||
private IrisCaveProfile resolveDominantCaveBiomeProfile(int chunkX, int chunkZ) {
|
||||
int[] offsets = new int[]{1, 4, 8, 12, 15};
|
||||
Map<IrisCaveProfile, Integer> profileVotes = new IdentityHashMap<>();
|
||||
int validSamples = 0;
|
||||
IrisCaveProfile dominantProfile = null;
|
||||
int dominantVotes = 0;
|
||||
|
||||
for (int offsetX : offsets) {
|
||||
for (int offsetZ : offsets) {
|
||||
int sampleX = (chunkX << 4) + offsetX;
|
||||
int sampleZ = (chunkZ << 4) + offsetZ;
|
||||
int surfaceY = getEngineMantle().getEngine().getHeight(sampleX, sampleZ, true);
|
||||
int sampleY = Math.max(1, surfaceY - 56);
|
||||
IrisBiome caveBiome = getEngineMantle().getEngine().getCaveBiome(sampleX, sampleY, sampleZ);
|
||||
if (caveBiome == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IrisCaveProfile profile = caveBiome.getCaveProfile();
|
||||
if (!isProfileEnabled(profile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int votes = profileVotes.getOrDefault(profile, 0) + 1;
|
||||
profileVotes.put(profile, votes);
|
||||
validSamples++;
|
||||
if (votes > dominantVotes) {
|
||||
dominantVotes = votes;
|
||||
dominantProfile = profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dominantProfile == null || validSamples <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int requiredVotes = Math.max(13, (int) Math.ceil(validSamples * 0.65D));
|
||||
if (dominantVotes < requiredVotes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return dominantProfile;
|
||||
}
|
||||
|
||||
private IrisCaveProfile resolveActiveProfile(IrisCaveProfile dimensionProfile, IrisCaveProfile regionProfile, IrisCaveProfile surfaceBiomeProfile, IrisCaveProfile caveBiomeProfile) {
|
||||
if (isProfileEnabled(caveBiomeProfile)) {
|
||||
return caveBiomeProfile;
|
||||
}
|
||||
|
||||
if (isProfileEnabled(surfaceBiomeProfile)) {
|
||||
return surfaceBiomeProfile;
|
||||
}
|
||||
|
||||
if (isProfileEnabled(regionProfile)) {
|
||||
|
||||
@@ -64,7 +64,12 @@ public class MantleObjectComponent extends IrisMantleComponent {
|
||||
int zzz = 8 + (z << 4);
|
||||
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
|
||||
IrisBiome surfaceBiome = getComplex().getTrueBiomeStream().get(xxx, zzz);
|
||||
IrisBiome caveBiome = getComplex().getCaveBiomeStream().get(xxx, zzz);
|
||||
int surfaceY = getEngineMantle().getEngine().getHeight(xxx, zzz, true);
|
||||
int sampleY = Math.max(1, surfaceY - 48);
|
||||
IrisBiome caveBiome = getEngineMantle().getEngine().getCaveBiome(xxx, sampleY, zzz);
|
||||
if (caveBiome == null) {
|
||||
caveBiome = surfaceBiome;
|
||||
}
|
||||
if (traceRegen) {
|
||||
Iris.info("Regen object layer start: chunk=" + x + "," + z
|
||||
+ " surfaceBiome=" + surfaceBiome.getLoadKey()
|
||||
|
||||
@@ -123,7 +123,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
||||
|
||||
walls.forEach((i, v) -> {
|
||||
IrisBiome biome = v.getCustomBiome().isEmpty()
|
||||
? getEngine().getCaveBiome(i.getX() + (x << 4), i.getZ() + (z << 4))
|
||||
? getEngine().getCaveBiome(i.getX() + (x << 4), i.getY(), i.getZ() + (z << 4))
|
||||
: getEngine().getData().getBiomeLoader().load(v.getCustomBiome());
|
||||
|
||||
if (biome != null) {
|
||||
@@ -207,7 +207,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
||||
}
|
||||
|
||||
IrisBiome biome = customBiome.isEmpty()
|
||||
? getEngine().getCaveBiome(xx, zz)
|
||||
? getEngine().getCaveBiome(xx, center, zz)
|
||||
: getEngine().getData().getBiomeLoader().load(customBiome);
|
||||
|
||||
if (biome == null) {
|
||||
|
||||
@@ -137,6 +137,10 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
@RegistryListResource(IrisBiome.class)
|
||||
@Desc("The carving biome. If specified the biome will be used when under a carving instead of this current biome.")
|
||||
private String carvingBiome = "";
|
||||
@MinNumber(0)
|
||||
@MaxNumber(256)
|
||||
@Desc("Minimum depth below terrain surface required before this cave biome can be selected.")
|
||||
private int caveMinDepthBelowSurface = 0;
|
||||
@Desc("The default slab if iris decides to place a slab in this biome. Default is no slab.")
|
||||
private IrisBiomePaletteLayer slab = new IrisBiomePaletteLayer().zero();
|
||||
@Desc("The default wall if iris decides to place a wall higher than 2 blocks (steep hills or possibly cliffs)")
|
||||
|
||||
@@ -24,6 +24,16 @@ public class IrisCaveProfile {
|
||||
@Desc("Global vertical bounds for profile cave carving.")
|
||||
private IrisRange verticalRange = new IrisRange(0, 384);
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(128)
|
||||
@Desc("Vertical fade range applied near cave profile min/max bounds to avoid abrupt hard-stop ceilings/floors.")
|
||||
private int verticalEdgeFade = 20;
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(1)
|
||||
@Desc("Strength of the vertical edge fade at cave profile min/max bounds.")
|
||||
private double verticalEdgeFadeStrength = 0.18;
|
||||
|
||||
@Desc("Base density style for cave field generation.")
|
||||
private IrisGeneratorStyle baseDensityStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style();
|
||||
|
||||
@@ -58,6 +68,16 @@ public class IrisCaveProfile {
|
||||
@Desc("Vertical sample step used while evaluating cave density.")
|
||||
private int sampleStep = 2;
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(4096)
|
||||
@Desc("Minimum carved cells expected from this profile before recovery boost applies.")
|
||||
private int minCarveCells = 0;
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(1)
|
||||
@Desc("Additional threshold boost used when profile carve output is too sparse.")
|
||||
private double recoveryThresholdBoost = 0.08;
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(64)
|
||||
@Desc("Minimum solid clearance below terrain surface where carving may occur.")
|
||||
|
||||
@@ -205,9 +205,12 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
int blockZ = z << 2;
|
||||
int blockY = y << 2;
|
||||
int surfaceY = engine.getComplex().getHeightStream().get(blockX, blockZ).intValue();
|
||||
boolean underground = blockY <= surfaceY - 2;
|
||||
int caveSwitchY = Math.min(-8, engine.getMinHeight() + 40);
|
||||
boolean deepUnderground = blockY <= caveSwitchY;
|
||||
boolean belowSurface = blockY <= surfaceY - 8;
|
||||
boolean underground = deepUnderground && belowSurface;
|
||||
IrisBiome irisBiome = underground
|
||||
? engine.getComplex().getCaveBiomeStream().get(blockX, blockZ)
|
||||
? engine.getCaveBiome(blockX, blockY, blockZ)
|
||||
: engine.getComplex().getTrueBiomeStream().get(blockX, blockZ);
|
||||
if (irisBiome == null && underground) {
|
||||
irisBiome = engine.getComplex().getTrueBiomeStream().get(blockX, blockZ);
|
||||
|
||||
Reference in New Issue
Block a user