112 lines
3.5 KiB
Java
112 lines
3.5 KiB
Java
package net.minecraft.world.level.biome;
|
|
|
|
import com.google.common.hash.Hashing;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.core.QuartPos;
|
|
import net.minecraft.util.LinearCongruentialGenerator;
|
|
import net.minecraft.util.Mth;
|
|
|
|
public class BiomeManager {
|
|
public static final int CHUNK_CENTER_QUART = QuartPos.fromBlock(8);
|
|
private static final int ZOOM_BITS = 2;
|
|
private static final int ZOOM = 4;
|
|
private static final int ZOOM_MASK = 3;
|
|
private final BiomeManager.NoiseBiomeSource noiseBiomeSource;
|
|
private final long biomeZoomSeed;
|
|
|
|
public BiomeManager(BiomeManager.NoiseBiomeSource noiseBiomeSource, long biomeZoomSeed) {
|
|
this.noiseBiomeSource = noiseBiomeSource;
|
|
this.biomeZoomSeed = biomeZoomSeed;
|
|
}
|
|
|
|
public static long obfuscateSeed(long seed) {
|
|
return Hashing.sha256().hashLong(seed).asLong();
|
|
}
|
|
|
|
public BiomeManager withDifferentSource(BiomeManager.NoiseBiomeSource newSource) {
|
|
return new BiomeManager(newSource, this.biomeZoomSeed);
|
|
}
|
|
|
|
public Holder<Biome> getBiome(BlockPos pos) {
|
|
int i = pos.getX() - 2;
|
|
int j = pos.getY() - 2;
|
|
int k = pos.getZ() - 2;
|
|
int l = i >> 2;
|
|
int m = j >> 2;
|
|
int n = k >> 2;
|
|
double d = (i & 3) / 4.0;
|
|
double e = (j & 3) / 4.0;
|
|
double f = (k & 3) / 4.0;
|
|
int o = 0;
|
|
double g = Double.POSITIVE_INFINITY;
|
|
|
|
for (int p = 0; p < 8; p++) {
|
|
boolean bl = (p & 4) == 0;
|
|
boolean bl2 = (p & 2) == 0;
|
|
boolean bl3 = (p & 1) == 0;
|
|
int q = bl ? l : l + 1;
|
|
int r = bl2 ? m : m + 1;
|
|
int s = bl3 ? n : n + 1;
|
|
double h = bl ? d : d - 1.0;
|
|
double t = bl2 ? e : e - 1.0;
|
|
double u = bl3 ? f : f - 1.0;
|
|
double v = getFiddledDistance(this.biomeZoomSeed, q, r, s, h, t, u);
|
|
if (g > v) {
|
|
o = p;
|
|
g = v;
|
|
}
|
|
}
|
|
|
|
int px = (o & 4) == 0 ? l : l + 1;
|
|
int w = (o & 2) == 0 ? m : m + 1;
|
|
int x = (o & 1) == 0 ? n : n + 1;
|
|
return this.noiseBiomeSource.getNoiseBiome(px, w, x);
|
|
}
|
|
|
|
public Holder<Biome> getNoiseBiomeAtPosition(double x, double y, double z) {
|
|
int i = QuartPos.fromBlock(Mth.floor(x));
|
|
int j = QuartPos.fromBlock(Mth.floor(y));
|
|
int k = QuartPos.fromBlock(Mth.floor(z));
|
|
return this.getNoiseBiomeAtQuart(i, j, k);
|
|
}
|
|
|
|
public Holder<Biome> getNoiseBiomeAtPosition(BlockPos pos) {
|
|
int i = QuartPos.fromBlock(pos.getX());
|
|
int j = QuartPos.fromBlock(pos.getY());
|
|
int k = QuartPos.fromBlock(pos.getZ());
|
|
return this.getNoiseBiomeAtQuart(i, j, k);
|
|
}
|
|
|
|
public Holder<Biome> getNoiseBiomeAtQuart(int x, int y, int z) {
|
|
return this.noiseBiomeSource.getNoiseBiome(x, y, z);
|
|
}
|
|
|
|
private static double getFiddledDistance(long seed, int x, int y, int z, double xNoise, double yNoise, double zNoise) {
|
|
long l = LinearCongruentialGenerator.next(seed, x);
|
|
l = LinearCongruentialGenerator.next(l, y);
|
|
l = LinearCongruentialGenerator.next(l, z);
|
|
l = LinearCongruentialGenerator.next(l, x);
|
|
l = LinearCongruentialGenerator.next(l, y);
|
|
l = LinearCongruentialGenerator.next(l, z);
|
|
double d = getFiddle(l);
|
|
l = LinearCongruentialGenerator.next(l, seed);
|
|
double e = getFiddle(l);
|
|
l = LinearCongruentialGenerator.next(l, seed);
|
|
double f = getFiddle(l);
|
|
return Mth.square(zNoise + f) + Mth.square(yNoise + e) + Mth.square(xNoise + d);
|
|
}
|
|
|
|
private static double getFiddle(long seed) {
|
|
double d = Math.floorMod(seed >> 24, 1024) / 1024.0;
|
|
return (d - 0.5) * 0.9;
|
|
}
|
|
|
|
public interface NoiseBiomeSource {
|
|
/**
|
|
* Gets the biome at the given quart positions.
|
|
* Note that the coordinates passed into this method are 1/4 the scale of block coordinates.
|
|
*/
|
|
Holder<Biome> getNoiseBiome(int x, int y, int z);
|
|
}
|
|
}
|