116 lines
4.1 KiB
Java
116 lines
4.1 KiB
Java
package net.minecraft.world.level.levelgen;
|
|
|
|
import java.util.function.LongFunction;
|
|
import net.minecraft.util.RandomSource;
|
|
|
|
public class WorldgenRandom extends LegacyRandomSource {
|
|
private final RandomSource randomSource;
|
|
private int count;
|
|
|
|
public WorldgenRandom(RandomSource randomSource) {
|
|
super(0L);
|
|
this.randomSource = randomSource;
|
|
}
|
|
|
|
public int getCount() {
|
|
return this.count;
|
|
}
|
|
|
|
@Override
|
|
public RandomSource fork() {
|
|
return this.randomSource.fork();
|
|
}
|
|
|
|
@Override
|
|
public PositionalRandomFactory forkPositional() {
|
|
return this.randomSource.forkPositional();
|
|
}
|
|
|
|
@Override
|
|
public int next(int size) {
|
|
this.count++;
|
|
return this.randomSource instanceof LegacyRandomSource legacyRandomSource ? legacyRandomSource.next(size) : (int)(this.randomSource.nextLong() >>> 64 - size);
|
|
}
|
|
|
|
@Override
|
|
public synchronized void setSeed(long seed) {
|
|
if (this.randomSource != null) {
|
|
this.randomSource.setSeed(seed);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Seeds the current random for chunk decoration, including spawning mobs and for use in feature placement.
|
|
* The coordinates correspond to the minimum block position within a given chunk.
|
|
*/
|
|
public long setDecorationSeed(long levelSeed, int minChunkBlockX, int minChunkBlockZ) {
|
|
this.setSeed(levelSeed);
|
|
long l = this.nextLong() | 1L;
|
|
long m = this.nextLong() | 1L;
|
|
long n = minChunkBlockX * l + minChunkBlockZ * m ^ levelSeed;
|
|
this.setSeed(n);
|
|
return n;
|
|
}
|
|
|
|
/**
|
|
* Seeds the current random for placing features.
|
|
* Each feature is seeded differently in order to seem more random. However, it does not do a good job of this, and issues can arise from the salt being small with features that have the same decoration step and are close together in the feature lists.
|
|
*
|
|
* @param decorationSeed The seed computed by {@link #setDecorationSeed(long, int, int)}
|
|
* @param index The cumulative index of the generating feature within the biome's list of features.
|
|
* @param decorationStep The ordinal of the {@link net.minecraft.world.level.levelgen.GenerationStep.Decoration} of the generating feature.
|
|
*/
|
|
public void setFeatureSeed(long decorationSeed, int index, int decorationStep) {
|
|
long l = decorationSeed + index + 10000 * decorationStep;
|
|
this.setSeed(l);
|
|
}
|
|
|
|
/**
|
|
* Seeds the current random for placing large features such as caves, strongholds, and mineshafts.
|
|
*
|
|
* @param baseSeed This is passed in as the level seed, or in some cases such as carvers, as an offset from the level seed unique to each carver.
|
|
*/
|
|
public void setLargeFeatureSeed(long baseSeed, int chunkX, int chunkZ) {
|
|
this.setSeed(baseSeed);
|
|
long l = this.nextLong();
|
|
long m = this.nextLong();
|
|
long n = chunkX * l ^ chunkZ * m ^ baseSeed;
|
|
this.setSeed(n);
|
|
}
|
|
|
|
/**
|
|
* Seeds the current random for placing the starts of structure features.
|
|
* The region coordinates are the region which the target chunk lies in. For example, witch hut regions are 32x32 chunks, so all chunks within that region would be seeded identically.
|
|
* The size of the regions themselves are determined by the {@code spacing} of the structure settings.
|
|
*
|
|
* @param salt A salt unique to each structure.
|
|
*/
|
|
public void setLargeFeatureWithSalt(long levelSeed, int regionX, int regionZ, int salt) {
|
|
long l = regionX * 341873128712L + regionZ * 132897987541L + levelSeed + salt;
|
|
this.setSeed(l);
|
|
}
|
|
|
|
/**
|
|
* Creates a new {@code RandomSource}, seeded for determining whether a chunk is a slime chunk or not.
|
|
*
|
|
* @param salt For vanilla slimes, this is always {@code 987234911L}
|
|
*/
|
|
public static RandomSource seedSlimeChunk(int chunkX, int chunkZ, long levelSeed, long salt) {
|
|
return RandomSource.create(levelSeed + chunkX * chunkX * 4987142 + chunkX * 5947611 + chunkZ * chunkZ * 4392871L + chunkZ * 389711 ^ salt);
|
|
}
|
|
|
|
public static enum Algorithm {
|
|
LEGACY(LegacyRandomSource::new),
|
|
XOROSHIRO(XoroshiroRandomSource::new);
|
|
|
|
private final LongFunction<RandomSource> constructor;
|
|
|
|
private Algorithm(final LongFunction<RandomSource> constructor) {
|
|
this.constructor = constructor;
|
|
}
|
|
|
|
public RandomSource newInstance(long seed) {
|
|
return (RandomSource)this.constructor.apply(seed);
|
|
}
|
|
}
|
|
}
|