Add compute_density_function to replace removed `sample_noise (#1591)
This commit is contained in:
1 parent
d26a56ea98
commit
f2c658bf03
10 files changed
+141
-318
No files matched your search
@@ -1,5 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface NoiseColumnSamplerInterface {
|
||||
double getNoiseSample(String name, int x, int y, int z);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
|
||||
public interface RandomStateVisitorAccessor {
|
||||
DensityFunction.Visitor getVisitor();
|
||||
}
|
||||
@@ -1,265 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.NoiseColumnSamplerInterface;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import net.minecraft.core.QuartPos;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.levelgen.NoiseRouter;
|
||||
import net.minecraft.world.level.levelgen.NoiseRouterData;
|
||||
//import net.minecraft.world.level.levelgen.NoiseSampler;
|
||||
import net.minecraft.world.level.levelgen.NoiseSettings;
|
||||
//import net.minecraft.world.level.levelgen.TerrainInfo;
|
||||
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||
import net.minecraft.world.level.levelgen.synth.BlendedNoise;
|
||||
import net.minecraft.world.level.levelgen.synth.NoiseUtils;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
import net.minecraft.world.level.levelgen.synth.SimplexNoise;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(NoiseRouterData.class)
|
||||
public abstract class NoiseSampler_scarpetMixin implements NoiseColumnSamplerInterface {
|
||||
|
||||
/*
|
||||
@Shadow @Final
|
||||
private NoiseRouter router;
|
||||
|
||||
@Shadow @Final
|
||||
private BlendedNoise blendedNoise;
|
||||
|
||||
@Shadow @Final @Nullable
|
||||
private SimplexNoise islandNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise barrierNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise fluidLevelFloodednessNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise fluidLevelSpreadNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise lavaNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise pillarRarenessModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise pillarThicknessModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti2DElevationModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti2DRarityModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti2DThicknessModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti3DNoiseSource1;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti3DNoiseSource2;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti3DRarityModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghetti3DThicknessModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise spaghettiRoughnessModulator;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise cheeseNoiseSource;
|
||||
|
||||
@Shadow @Final
|
||||
private NormalNoise gapNoise;
|
||||
|
||||
@Shadow @Final
|
||||
private NoiseSettings noiseSettings;
|
||||
|
||||
@Shadow
|
||||
protected abstract double sampleJaggedNoise(double d, double e, double f);
|
||||
|
||||
@Shadow
|
||||
protected abstract double getLayerizedCaverns(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract double getPillars(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract double getSpaghetti2D(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract double getSpaghetti3D(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract double spaghettiRoughness(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract double getBigEntrances(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
public abstract double getOffset(int x, int y, int z);
|
||||
|
||||
@Shadow
|
||||
private static double sampleWithRarity(NormalNoise sampler, double x, double y, double z, double invertedScale) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract Climate.TargetPoint sample(int i, int j, int k);
|
||||
|
||||
@Shadow
|
||||
public abstract TerrainInfo terrainInfo(int x, int z, float continentalness, float weirdness, float erosion, Blender blender);
|
||||
|
||||
@Override
|
||||
public double getNoiseSample(String name, int x, int y, int z) {
|
||||
Climate.TargetPoint noiseValuePoint = this.sample(x, y, z);
|
||||
TerrainInfo terrainNoisePoint = terrainInfo(
|
||||
x,
|
||||
z,
|
||||
Climate.unquantizeCoord(noiseValuePoint.continentalness()),
|
||||
Climate.unquantizeCoord(noiseValuePoint.weirdness()),
|
||||
Climate.unquantizeCoord(noiseValuePoint.erosion()),
|
||||
Blender.empty()
|
||||
);
|
||||
switch (name) {
|
||||
case "temperature" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.temperature());
|
||||
}
|
||||
case "humidity" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.humidity());
|
||||
}
|
||||
case "continentalness" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.continentalness());
|
||||
}
|
||||
case "erosion" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.erosion());
|
||||
}
|
||||
case "weirdness" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.weirdness());
|
||||
}
|
||||
case "depth" -> {
|
||||
return Climate.unquantizeCoord(noiseValuePoint.depth());
|
||||
}
|
||||
case "shiftX" -> {
|
||||
return x + this.getOffset(x, 0, z);
|
||||
}
|
||||
case "shiftY" -> {
|
||||
return y + this.getOffset(y, z, x);
|
||||
}
|
||||
case "shiftZ" -> {
|
||||
return z + this.getOffset(z, x, 0);
|
||||
}
|
||||
case "terrain" -> {
|
||||
return this.blendedNoise.calculateNoise(x, y, z);
|
||||
}
|
||||
case "island" -> {
|
||||
return this.islandNoise == null ? 0 : this.islandNoise.getValue(x, y, z);
|
||||
}
|
||||
case "jagged" -> {
|
||||
return this.sampleJaggedNoise(terrainNoisePoint.jaggedness(), x, z);
|
||||
}
|
||||
case "aquiferBarrier" -> {
|
||||
return this.barrierNoise.getValue(x, y, z);
|
||||
}
|
||||
case "aquiferFluidLevelFloodedness" -> {
|
||||
return this.fluidLevelFloodednessNoise.getValue(x, y, z);
|
||||
}
|
||||
case "aquiferFluidLevelSpread" -> {
|
||||
return this.fluidLevelSpreadNoise.getValue(x, y, z);
|
||||
}
|
||||
case "aquiferLava" -> {
|
||||
return this.lavaNoise.getValue(x, y, z);
|
||||
}
|
||||
case "pillar" -> {
|
||||
return this.getPillars(x, y, z);
|
||||
}
|
||||
case "pillarRareness" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.pillarRarenessModulator, x, y, z, 0.0D, 2.0D);
|
||||
}
|
||||
case "pillarThickness" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.pillarThicknessModulator, x, y, z, 0.0D, 1.1D);
|
||||
}
|
||||
case "spaghetti2d" -> {
|
||||
return this.getSpaghetti2D(x, y, z);
|
||||
}
|
||||
case "spaghetti2dElevation" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti2DElevationModulator, x, 0.0, z, this.noiseSettings.getMinCellY(), 8.0);
|
||||
}
|
||||
case "spaghetti2dModulator" -> {
|
||||
return this.spaghetti2DRarityModulator.getValue(x * 2, y, z * 2);
|
||||
}
|
||||
case "spaghetti2dThickness" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti2DThicknessModulator, x * 2, y, z * 2, 0.6, 1.3);
|
||||
}
|
||||
case "spaghetti3d" -> {
|
||||
return this.getSpaghetti3D(x, y, z);
|
||||
}
|
||||
case "spaghetti3dFirst" -> {
|
||||
double d = this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2);
|
||||
double e = QuantizedSpaghettiRarityMixin_scarpetMixin.invokeGetSpaghettiRarity3D(d);
|
||||
return sampleWithRarity(this.spaghetti3DNoiseSource1, x, y, z, e);
|
||||
}
|
||||
case "spaghetti3dSecond" -> {
|
||||
double d = this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2);
|
||||
double e = QuantizedSpaghettiRarityMixin_scarpetMixin.invokeGetSpaghettiRarity3D(d);
|
||||
return sampleWithRarity(this.spaghetti3DNoiseSource2, x, y, z, e);
|
||||
}
|
||||
case "spaghetti3dRarity" -> {
|
||||
return this.spaghetti3DRarityModulator.getValue(x * 2, y, z * 2);
|
||||
}
|
||||
case "spaghetti3dThickness" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.spaghetti3DThicknessModulator, x, y, z, 0.065, 0.088);
|
||||
}
|
||||
case "spaghettiRoughness" -> {
|
||||
return this.spaghettiRoughness(x, y, z);
|
||||
}
|
||||
case "spaghettiRoughnessModulator" -> {
|
||||
return NoiseUtils.sampleNoiseAndMapToRange(this.spaghettiRoughnessModulator, x, y, z, 0.0, 0.1);
|
||||
}
|
||||
case "caveEntrance" -> {
|
||||
return this.getBigEntrances(
|
||||
QuartPos.toBlock(x),
|
||||
QuartPos.toBlock(y),
|
||||
QuartPos.toBlock(z)
|
||||
);
|
||||
}
|
||||
case "caveLayer" -> {
|
||||
// scaling them by 4 because it's sampled in normal coords
|
||||
return this.getLayerizedCaverns(
|
||||
QuartPos.toBlock(x),
|
||||
QuartPos.toBlock(y),
|
||||
QuartPos.toBlock(z)
|
||||
);
|
||||
}
|
||||
case "caveCheese" -> {
|
||||
// same reason as above
|
||||
return this.cheeseNoiseSource.getValue(
|
||||
QuartPos.toBlock(x),
|
||||
QuartPos.toBlock(y) / 1.5,
|
||||
QuartPos.toBlock(z)
|
||||
);
|
||||
}
|
||||
case "terrainPeaks" -> {
|
||||
return terrainNoisePoint.jaggedness();
|
||||
}
|
||||
case "terrainOffset" -> {
|
||||
return terrainNoisePoint.offset();
|
||||
}
|
||||
case "terrainFactor" -> {
|
||||
return terrainNoisePoint.factor();
|
||||
}
|
||||
case "oreGap" -> {
|
||||
return this.gapNoise.getValue(x, y, z);
|
||||
}
|
||||
}
|
||||
throw new InternalExpressionException("Unknown noise type: " + name);
|
||||
}*/
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
//import net.minecraft.world.level.levelgen.NoiseRouterData;
|
||||
//import net.minecraft.world.level.levelgen.NoiseSampler;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
|
||||
@Mixin(targets = "net.minecraft.world.level.levelgen.NoiseRouterData$QuantizedSpaghettiRarity")
|
||||
public interface QuantizedSpaghettiRarityMixin_scarpetMixin {
|
||||
@Invoker
|
||||
static double invokeGetSpaghettiRarity3D(double d) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.RandomStateVisitorAccessor;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(RandomState.class)
|
||||
public class RandomState_ScarpetMixin implements RandomStateVisitorAccessor {
|
||||
@Unique
|
||||
private DensityFunction.Visitor visitor;
|
||||
|
||||
@ModifyArg(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;"
|
||||
),
|
||||
index = 0
|
||||
)
|
||||
private DensityFunction.Visitor captureVisitor(DensityFunction.Visitor visitor) {
|
||||
this.visitor = visitor;
|
||||
return visitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DensityFunction.Visitor getVisitor() {
|
||||
return this.visitor;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.script.api;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.ChunkGeneratorInterface;
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.RandomStateVisitorAccessor;
|
||||
import carpet.fakes.ServerChunkManagerInterface;
|
||||
import carpet.fakes.ServerWorldInterface;
|
||||
import carpet.fakes.SpawnHelperInnerInterface;
|
||||
@@ -41,15 +42,22 @@ import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.QuartPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseRouter;
|
||||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureType;
|
||||
import net.minecraft.world.level.levelgen.synth.NormalNoise;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -1626,23 +1634,68 @@ public class WorldAccess {
|
||||
}
|
||||
|
||||
@ScarpetFunction(maxParams = -1)
|
||||
public Value sample_noise(Context c, @Locator.Block BlockPos pos, String... noiseQueries) {
|
||||
return Value.NULL;
|
||||
/*
|
||||
int mappedX = QuartPos.fromBlock(pos.getX());
|
||||
int mappedY = QuartPos.fromBlock(pos.getY());
|
||||
int mappedZ = QuartPos.fromBlock(pos.getZ());
|
||||
Climate.Sampler mns = ((CarpetContext) c).s.getLevel().getChunkSource().getGenerator().climateSampler();
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
public Value compute_density_function(Context c, @Locator.Block BlockPos pos, String... densityFunctionQueries) {
|
||||
|
||||
if (noiseQueries.length == 0) {
|
||||
noiseQueries = new String[]{"continentalness", "erosion", "weirdness", "temperature", "humidity", "depth"};
|
||||
Map<Value, Value> result = new HashMap<>();
|
||||
|
||||
ServerLevel level = ((CarpetContext) c).level();
|
||||
Registry<DensityFunction> densityFunctionRegistry = level.registryAccess().registryOrThrow(Registries.DENSITY_FUNCTION);
|
||||
|
||||
if (densityFunctionQueries.length == 0) {
|
||||
return ListValue.wrap(densityFunctionRegistry.keySet().stream().map(ValueConversions::of));
|
||||
}
|
||||
|
||||
for (String noise : noiseQueries) {
|
||||
double noiseValue = ((NoiseColumnSamplerInterface) mns).getNoiseSample(noise, mappedX, mappedY, mappedZ);
|
||||
ret.put(new StringValue(noise), new NumericValue(noiseValue));
|
||||
ChunkGenerator chunkGenerator = level.getChunkSource().getGenerator();
|
||||
if (!(chunkGenerator instanceof NoiseBasedChunkGenerator generator)) {
|
||||
return MapValue.wrap(result);
|
||||
}
|
||||
return MapValue.wrap(ret);*/
|
||||
|
||||
RandomState randomState = RandomState.create(
|
||||
generator.generatorSettings().value(),
|
||||
level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed()
|
||||
);
|
||||
|
||||
DensityFunction.Visitor visitor = ((RandomStateVisitorAccessor) (Object) randomState).getVisitor();
|
||||
DensityFunction.SinglePointContext singlePointContext = new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ());
|
||||
NoiseRouter router = generator.generatorSettings().value().noiseRouter();
|
||||
|
||||
for (String densityFunctionQuery : densityFunctionQueries) {
|
||||
DensityFunction densityFunction = switch (densityFunctionQuery) {
|
||||
case "barrier_noise" -> router.barrierNoise();
|
||||
case "fluid_level_floodedness_noise" -> router.fluidLevelFloodednessNoise();
|
||||
case "fluid_level_spread_noise" -> router.fluidLevelSpreadNoise();
|
||||
case "lava_noise" -> router.lavaNoise();
|
||||
case "temperature" -> router.temperature();
|
||||
case "vegetation" -> router.vegetation();
|
||||
case "continents" -> router.continents();
|
||||
case "erosion" -> router.erosion();
|
||||
case "depth" -> router.depth();
|
||||
case "ridges" -> router.ridges();
|
||||
case "initial_density_without_jaggedness" -> router.initialDensityWithoutJaggedness();
|
||||
case "final_density" -> router.finalDensity();
|
||||
case "vein_toggle" -> router.veinToggle();
|
||||
case "vein_ridged" -> router.veinRidged();
|
||||
case "vein_gap" -> router.veinGap();
|
||||
default -> {
|
||||
ResourceLocation densityFunctionKey = InputValidator.identifierOf(densityFunctionQuery);
|
||||
|
||||
if (densityFunctionRegistry.containsKey(densityFunctionKey)) {
|
||||
yield densityFunctionRegistry.get(densityFunctionKey);
|
||||
}
|
||||
|
||||
throw new InternalExpressionException(
|
||||
"Density function '" + densityFunctionQuery + "' doesn't exist. " +
|
||||
"Please check the spelling or use with full 'namespace:value' if its custom defined."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (densityFunction == null) // IDE thinks may be null as Registry.get is Nullable, but we checked it
|
||||
throw new IllegalStateException("density function can't be null here");
|
||||
|
||||
double value = densityFunction.mapAll(visitor).compute(singlePointContext);
|
||||
result.put(StringValue.of(densityFunctionQuery), new NumericValue(value));
|
||||
}
|
||||
return MapValue.wrap(result);
|
||||
}
|
||||
}
|
||||
@@ -162,8 +162,7 @@
|
||||
"BlockPredicate_scarpetMixin",
|
||||
"TagPredicate_scarpetMixin",
|
||||
"HorseBaseEntity_scarpetMixin",
|
||||
"NoiseSampler_scarpetMixin",
|
||||
"QuantizedSpaghettiRarityMixin_scarpetMixin",
|
||||
"RandomState_ScarpetMixin",
|
||||
"Biome_scarpetMixin",
|
||||
|
||||
"BlockEntity_movableBEMixin",
|
||||
|
||||
Reference in new issue
Block a user