package net.minecraft.world.level.levelgen; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.level.biome.Climate.Sampler; import net.minecraft.world.level.levelgen.synth.BlendedNoise; import net.minecraft.world.level.levelgen.synth.NormalNoise; import net.minecraft.world.level.levelgen.synth.NormalNoise.NoiseParameters; public final class RandomState { final PositionalRandomFactory random; private final HolderGetter noises; private final NoiseRouter router; private final Sampler sampler; private final SurfaceSystem surfaceSystem; private final PositionalRandomFactory aquiferRandom; private final PositionalRandomFactory oreRandom; private final Map, NormalNoise> noiseIntances; private final Map positionalRandoms; public static RandomState create(HolderGetter.Provider registries, ResourceKey settingsKey, long levelSeed) { return create(registries.lookupOrThrow(Registries.NOISE_SETTINGS).getOrThrow(settingsKey).value(), registries.lookupOrThrow(Registries.NOISE), levelSeed); } public static RandomState create(NoiseGeneratorSettings settings, HolderGetter noiseParametersGetter, long levelSeed) { return new RandomState(settings, noiseParametersGetter, levelSeed); } private RandomState(NoiseGeneratorSettings settings, HolderGetter noiseParametersGetter, long levelSeed) { this.random = settings.getRandomSource().newInstance(levelSeed).forkPositional(); this.noises = noiseParametersGetter; this.aquiferRandom = this.random.fromHashOf(ResourceLocation.withDefaultNamespace("aquifer")).forkPositional(); this.oreRandom = this.random.fromHashOf(ResourceLocation.withDefaultNamespace("ore")).forkPositional(); this.noiseIntances = new ConcurrentHashMap(); this.positionalRandoms = new ConcurrentHashMap(); this.surfaceSystem = new SurfaceSystem(this, settings.defaultBlock(), settings.seaLevel(), this.random); final boolean bl = settings.useLegacyRandomSource(); class NoiseWiringHelper implements DensityFunction.Visitor { private final Map wrapped = new HashMap(); private RandomSource newLegacyInstance(long seed) { return new LegacyRandomSource(levelSeed + seed); } @Override public DensityFunction.NoiseHolder visitNoise(DensityFunction.NoiseHolder noiseHolder) { Holder holder = noiseHolder.noiseData(); if (bl) { if (holder.is(Noises.TEMPERATURE)) { NormalNoise normalNoise = NormalNoise.createLegacyNetherBiome(this.newLegacyInstance(0L), new NoiseParameters(-7, 1.0, 1.0)); return new DensityFunction.NoiseHolder(holder, normalNoise); } if (holder.is(Noises.VEGETATION)) { NormalNoise normalNoise = NormalNoise.createLegacyNetherBiome(this.newLegacyInstance(1L), new NoiseParameters(-7, 1.0, 1.0)); return new DensityFunction.NoiseHolder(holder, normalNoise); } if (holder.is(Noises.SHIFT)) { NormalNoise normalNoise = NormalNoise.create(RandomState.this.random.fromHashOf(Noises.SHIFT.location()), new NoiseParameters(0, 0.0)); return new DensityFunction.NoiseHolder(holder, normalNoise); } } NormalNoise normalNoise = RandomState.this.getOrCreateNoise((ResourceKey)holder.unwrapKey().orElseThrow()); return new DensityFunction.NoiseHolder(holder, normalNoise); } private DensityFunction wrapNew(DensityFunction densityFunction) { if (densityFunction instanceof BlendedNoise blendedNoise) { RandomSource randomSource = bl ? this.newLegacyInstance(0L) : RandomState.this.random.fromHashOf(ResourceLocation.withDefaultNamespace("terrain")); return blendedNoise.withNewRandom(randomSource); } else { return (DensityFunction)(densityFunction instanceof DensityFunctions.EndIslandDensityFunction ? new DensityFunctions.EndIslandDensityFunction(levelSeed) : densityFunction); } } @Override public DensityFunction apply(DensityFunction densityFunction) { return (DensityFunction)this.wrapped.computeIfAbsent(densityFunction, this::wrapNew); } } this.router = settings.noiseRouter().mapAll(new NoiseWiringHelper()); DensityFunction.Visitor visitor = new DensityFunction.Visitor() { private final Map wrapped = new HashMap(); private DensityFunction wrapNew(DensityFunction densityFunction) { if (densityFunction instanceof DensityFunctions.HolderHolder holderHolder) { return holderHolder.function().value(); } else { return densityFunction instanceof DensityFunctions.Marker marker ? marker.wrapped() : densityFunction; } } @Override public DensityFunction apply(DensityFunction densityFunction) { return (DensityFunction)this.wrapped.computeIfAbsent(densityFunction, this::wrapNew); } }; this.sampler = new Sampler( this.router.temperature().mapAll(visitor), this.router.vegetation().mapAll(visitor), this.router.continents().mapAll(visitor), this.router.erosion().mapAll(visitor), this.router.depth().mapAll(visitor), this.router.ridges().mapAll(visitor), settings.spawnTarget() ); } public NormalNoise getOrCreateNoise(ResourceKey resourceKey) { return (NormalNoise)this.noiseIntances.computeIfAbsent(resourceKey, resourceKey2 -> Noises.instantiate(this.noises, this.random, resourceKey)); } public PositionalRandomFactory getOrCreateRandomFactory(ResourceLocation location) { return (PositionalRandomFactory)this.positionalRandoms.computeIfAbsent(location, resourceLocation2 -> this.random.fromHashOf(location).forkPositional()); } public NoiseRouter router() { return this.router; } public Sampler sampler() { return this.sampler; } public SurfaceSystem surfaceSystem() { return this.surfaceSystem; } public PositionalRandomFactory aquiferRandom() { return this.aquiferRandom; } public PositionalRandomFactory oreRandom() { return this.oreRandom; } }