143 lines
3.2 KiB
Java
143 lines
3.2 KiB
Java
package ru.dbotthepony.mc.prng;
|
|
|
|
import it.unimi.dsi.fastutil.HashCommon;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian;
|
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
|
import net.minecraft.world.level.levelgen.RandomSupport;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.util.random.RandomGenerator;
|
|
|
|
public final class GJRAND64RandomSource implements RandomGenerator, RandomSource {
|
|
private long s0;
|
|
private long s1;
|
|
private long s2;
|
|
private long s3;
|
|
|
|
private final MarsagliaPolarGaussian gaussian = new MarsagliaPolarGaussian(this);
|
|
|
|
public GJRAND64RandomSource() {
|
|
reinitialize(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed());
|
|
}
|
|
|
|
public GJRAND64RandomSource(long seed) {
|
|
reinitialize(seed);
|
|
}
|
|
|
|
public GJRAND64RandomSource(long seed0, long seed1) {
|
|
reinitialize(seed0, seed1);
|
|
}
|
|
|
|
private void reinitialize(long seed) {
|
|
reinitialize(seed, 0L);
|
|
}
|
|
|
|
private void reinitialize(long seed0, long seed1) {
|
|
s0 = seed0;
|
|
s1 = seed1;
|
|
s2 = 2000001L;
|
|
s3 = 0L;
|
|
}
|
|
|
|
@Override
|
|
public @NotNull RandomSource fork() {
|
|
return new GJRAND64RandomSource(nextLong(), nextLong());
|
|
}
|
|
|
|
@Override
|
|
public @NotNull PositionalRandomFactory forkPositional() {
|
|
return new Positional(nextLong(), nextLong());
|
|
}
|
|
|
|
@Override
|
|
public void setSeed(long l) {
|
|
reinitialize(l);
|
|
gaussian.reset();
|
|
}
|
|
|
|
@Override
|
|
public int nextInt() {
|
|
return RandomGenerator.super.nextInt();
|
|
}
|
|
|
|
@Override
|
|
public int nextInt(int bound) {
|
|
return RandomGenerator.super.nextInt(bound);
|
|
}
|
|
|
|
@Override
|
|
public int nextInt(int origin, int bound) {
|
|
return RandomGenerator.super.nextInt(origin, bound);
|
|
}
|
|
|
|
@Override
|
|
public float nextFloat() {
|
|
return RandomGenerator.super.nextFloat();
|
|
}
|
|
|
|
@Override
|
|
public boolean nextBoolean() {
|
|
return RandomGenerator.super.nextBoolean();
|
|
}
|
|
|
|
@Override
|
|
public double nextDouble() {
|
|
return RandomGenerator.super.nextDouble();
|
|
}
|
|
|
|
@Override
|
|
public double nextGaussian() {
|
|
return gaussian.nextGaussian();
|
|
}
|
|
|
|
@Override
|
|
public long nextLong() {
|
|
s1 += s2;
|
|
s0 = Long.rotateLeft(s0, 32);
|
|
s2 ^= s1;
|
|
s3 += 0x55aa96a5L;
|
|
s0 += s1;
|
|
s2 = Long.rotateLeft(s2, 23);
|
|
s1 ^= s0;
|
|
s0 += s2;
|
|
s1 = Long.rotateLeft(s1, 19);
|
|
s2 += s0;
|
|
s1 += s3;
|
|
return s0;
|
|
}
|
|
|
|
public static class Positional implements PositionalRandomFactory {
|
|
private final long seed0;
|
|
private final long seed1;
|
|
|
|
public Positional(long seed0, long seed1) {
|
|
this.seed0 = seed0;
|
|
this.seed1 = seed1;
|
|
}
|
|
|
|
@Override
|
|
public @NotNull RandomSource fromHashOf(@NotNull String s) {
|
|
long seed = HashCommon.murmurHash3((long) s.hashCode() & 0xFFFFFFFFL);
|
|
return new GJRAND64RandomSource(seed0 ^ Long.rotateLeft(seed, 32), seed1 ^ seed);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull RandomSource fromSeed(long l) {
|
|
return new GJRAND64RandomSource(l);
|
|
}
|
|
|
|
@Override
|
|
public @NotNull RandomSource at(int x, int y, int z) {
|
|
long seed = Mth.getSeed(x, y, z);
|
|
return new GJRAND64RandomSource(seed0 ^ Long.rotateLeft(seed, 32), seed1 ^ seed);
|
|
}
|
|
|
|
@Override
|
|
public void parityConfigString(@NotNull StringBuilder stringBuilder) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
}
|
|
}
|