mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-25 04:51:03 -04:00
Fix 1.18 spawn and stronghold finders (please fix MC-241546, Mojang)
This commit is contained in:
parent
65414ac3be
commit
8fea920b49
@ -277,7 +277,7 @@ Strongholds as well as the world spawn point actually search until they find a s
|
||||
|
||||
int main()
|
||||
{
|
||||
int mc = MC_1_17;
|
||||
int mc = MC_1_18;
|
||||
uint64_t seed = 3055141959546LL;
|
||||
|
||||
// Only the first stronghold has a position which can be estimated
|
||||
|
137
finders.c
137
finders.c
@ -944,12 +944,17 @@ Pos locateBiome(
|
||||
x >>= 2;
|
||||
z >>= 2;
|
||||
radius >>= 2;
|
||||
uint64_t dat = 0;
|
||||
|
||||
for (i = -radius; i <= radius; i++)
|
||||
{
|
||||
for (j = -radius; j <= radius; j++)
|
||||
{
|
||||
int id = getBiomeAt(g, 4, x+i, y, z+j);
|
||||
for (i = -radius; i <= radius; i++)
|
||||
{
|
||||
int id, xi = x+i, zj = z+j;
|
||||
// emulate dependent biome generation MC-241546
|
||||
//id = getBiomeAt(g, 4, xi, y, zj);
|
||||
id = sampleBiomeNoise(&g->bn, NULL, xi, y, zj, &dat, 0);
|
||||
|
||||
if (!validBiomes[id]) continue;
|
||||
if (found == 0 || nextInt(rng, found+1) == 0)
|
||||
{
|
||||
@ -1114,28 +1119,29 @@ const char* getValidStrongholdBiomes(int mc)
|
||||
modified_gravelly_mountains, shattered_savanna,
|
||||
shattered_savanna_plateau, eroded_badlands,
|
||||
modified_wooded_badlands_plateau, modified_badlands_plateau,
|
||||
bamboo_jungle, bamboo_jungle_hills,
|
||||
bamboo_jungle, bamboo_jungle_hills, dripstone_caves, lush_caves, meadow,
|
||||
grove, snowy_slopes, stony_peaks, jagged_peaks, frozen_peaks,
|
||||
};
|
||||
|
||||
static char isValid115[256], isValid[256];
|
||||
unsigned int i;
|
||||
static char v15[256], v17[256], v18[256];
|
||||
char *valid = (mc <= MC_1_15 ? v15 : mc <= MC_1_17 ? v17 : v18);
|
||||
|
||||
if (mc <= MC_1_15)
|
||||
if (!valid[strongholdBiomes[0]])
|
||||
{
|
||||
if (!isValid115[strongholdBiomes[0]])
|
||||
for (i = 0; i < sizeof(strongholdBiomes) / sizeof(int); i++)
|
||||
isValid115[ strongholdBiomes[i] ] = 1;
|
||||
return isValid115;
|
||||
for (i = 0; i < sizeof(strongholdBiomes)/sizeof(int); i++)
|
||||
valid[ strongholdBiomes[i] ] = 1;
|
||||
|
||||
if (mc >= MC_1_18)
|
||||
{
|
||||
valid[stone_shore] = 0;
|
||||
}
|
||||
else
|
||||
else if (mc >= MC_1_16)
|
||||
{ // simulate MC-199298
|
||||
if (!isValid[strongholdBiomes[0]])
|
||||
for (i = 0; i < sizeof(strongholdBiomes) / sizeof(int); i++)
|
||||
isValid[ strongholdBiomes[i] ] = 1;
|
||||
isValid[bamboo_jungle] = 0;
|
||||
isValid[bamboo_jungle_hills] = 0;
|
||||
return isValid;
|
||||
valid[bamboo_jungle] = 0;
|
||||
valid[bamboo_jungle_hills] = 0;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
Pos initFirstStronghold(StrongholdIter *sh, int mc, uint64_t s48)
|
||||
@ -1343,6 +1349,79 @@ static int findServerSpawn(const Generator *g, int chunkX, int chunkZ,
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
uint64_t getSpawnDist(const Generator *g, int x, int z)
|
||||
{
|
||||
int64_t np[6];
|
||||
uint32_t flags = SAMPLE_NO_DEPTH | SAMPLE_NO_BIOME;
|
||||
sampleBiomeNoise(&g->bn, np, x>>2, 0, z>>2, NULL, flags);
|
||||
const int64_t spawn_np[][2] = {
|
||||
{-10000,10000},{-10000,10000},{-1100,10000},{-10000,10000},{0,0},
|
||||
{-10000,-1600},{1600,10000} // [6]: weirdness for the second noise point
|
||||
};
|
||||
uint64_t ds = 0, ds1 = 0, ds2 = 0;
|
||||
uint64_t a, b, q, i;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
a = +np[i] - (uint64_t)spawn_np[i][1];
|
||||
b = -np[i] + (uint64_t)spawn_np[i][0];
|
||||
q = (int64_t)a > 0 ? a : (int64_t)b > 0 ? b : 0;
|
||||
ds += q * q;
|
||||
}
|
||||
a = +np[5] - (uint64_t)spawn_np[5][1];
|
||||
b = -np[5] + (uint64_t)spawn_np[5][0];
|
||||
q = (int64_t)a > 0 ? a : (int64_t)b > 0 ? b : 0;
|
||||
ds1 = ds + q*q;
|
||||
a = +np[5] - (uint64_t)spawn_np[6][1];
|
||||
b = -np[5] + (uint64_t)spawn_np[6][0];
|
||||
q = (int64_t)a > 0 ? a : (int64_t)b > 0 ? b : 0;
|
||||
ds2 = ds + q*q;
|
||||
return ds1 <= ds2 ? ds1 : ds2;
|
||||
}
|
||||
|
||||
static
|
||||
void findFittest(const Generator *g, Pos *pos, uint64_t *fitness, double maxrad, double step)
|
||||
{
|
||||
double rad = step, ang = 0;
|
||||
Pos p = *pos;
|
||||
while (rad <= maxrad)
|
||||
{
|
||||
int x = p.x + (int)(sin(ang) * rad);
|
||||
int z = p.z + (int)(cos(ang) * rad);
|
||||
// calc fitness
|
||||
double d = ((double)x*x + (double)z*z) / (2500*2500);
|
||||
uint64_t fit = (uint64_t)(d*d * 1e8);
|
||||
// calculate the distance to the noise points for spawn
|
||||
fit += getSpawnDist(g, x, z);
|
||||
if (fit < *fitness)
|
||||
{
|
||||
pos->x = x;
|
||||
pos->z = z;
|
||||
*fitness = fit;
|
||||
}
|
||||
|
||||
ang += step / rad;
|
||||
if (ang <= M_PI*2)
|
||||
continue;
|
||||
ang = 0;
|
||||
rad += step;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
Pos findFittestPos(const Generator *g)
|
||||
{
|
||||
Pos spawn = {0, 0};
|
||||
uint64_t fitness = getSpawnDist(g, 0, 0);
|
||||
findFittest(g, &spawn, &fitness, 2048.0, 512.0);
|
||||
findFittest(g, &spawn, &fitness, 512.0, 32.0);
|
||||
// center of chunk
|
||||
spawn.x = ((spawn.x >> 4) << 4) + 8;
|
||||
spawn.z = ((spawn.z >> 4) << 4) + 8;
|
||||
return spawn;
|
||||
}
|
||||
|
||||
|
||||
Pos getSpawn(const Generator *g)
|
||||
{
|
||||
const char *isSpawnBiome = getValidSpawnBiomes();
|
||||
@ -1351,14 +1430,19 @@ Pos getSpawn(const Generator *g)
|
||||
int i;
|
||||
|
||||
uint64_t rnd;
|
||||
if (g->mc <= MC_1_17)
|
||||
{
|
||||
setSeed(&rnd, g->seed);
|
||||
spawn = locateBiome(g, 0, 63, 0, 256, isSpawnBiome, &rnd, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
//printf("Unable to find spawn biome.\n");
|
||||
spawn.x = spawn.z = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn = findFittestPos(g);
|
||||
}
|
||||
|
||||
double accum = 1;
|
||||
double bx = 0;
|
||||
@ -1374,7 +1458,7 @@ Pos getSpawn(const Generator *g)
|
||||
{
|
||||
if (j > -16 && j <= 16 && k > -16 && k <= 16)
|
||||
{
|
||||
if (findServerSpawn(g, (spawn.x>>4)+j, (spawn.x>>4)+k,
|
||||
if (findServerSpawn(g, (spawn.x>>4)+j, (spawn.z>>4)+k,
|
||||
&bx, &bz, &bn, &accum))
|
||||
{
|
||||
spawn.x = (int) round(bx / bn);
|
||||
@ -1420,26 +1504,31 @@ Pos getSpawn(const Generator *g)
|
||||
return spawn;
|
||||
}
|
||||
|
||||
|
||||
Pos estimateSpawn(const Generator *g)
|
||||
{
|
||||
const char *isSpawnBiome = getValidSpawnBiomes();
|
||||
Pos spawn;
|
||||
|
||||
if (g->mc <= MC_1_17)
|
||||
{
|
||||
int found;
|
||||
uint64_t rnd;
|
||||
setSeed(&rnd, g->seed);
|
||||
spawn = locateBiome(g, 0, 63, 0, 256, isSpawnBiome, &rnd, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
spawn.x = spawn.z = 8;
|
||||
}
|
||||
|
||||
if (g->mc >= MC_1_13)
|
||||
{
|
||||
spawn.x &= ~0xf;
|
||||
spawn.z &= ~0xf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn = findFittestPos(g);
|
||||
}
|
||||
|
||||
return spawn;
|
||||
}
|
||||
|
34
layers.c
34
layers.c
@ -1354,11 +1354,12 @@ int p2overworld(const uint64_t np[6], uint64_t *dat);
|
||||
#endif
|
||||
|
||||
/// Biome sampler for MC 1.18
|
||||
int sampleBiomeNoise(const BiomeNoise *bn, int x, int y, int z, uint64_t *dat, int approx)
|
||||
int sampleBiomeNoise(const BiomeNoise *bn, int64_t *np, int x, int y, int z,
|
||||
uint64_t *dat, uint32_t flags)
|
||||
{
|
||||
float t = 0, h = 0, c = 0, e = 0, d = 0, w = 0;
|
||||
double px = x, pz = z;
|
||||
if (approx == 0)
|
||||
if (!(flags & SAMPLE_NO_SHIFT))
|
||||
{
|
||||
px += sampleDoublePerlin(&bn->shift, x, 0, z) * 4.0;
|
||||
pz += sampleDoublePerlin(&bn->shift, z, x, 0) * 4.0;
|
||||
@ -1368,6 +1369,8 @@ int sampleBiomeNoise(const BiomeNoise *bn, int x, int y, int z, uint64_t *dat, i
|
||||
e = sampleDoublePerlin(&bn->erosion, px, 0, pz);
|
||||
w = sampleDoublePerlin(&bn->weirdness, px, 0, pz);
|
||||
|
||||
if (!(flags & SAMPLE_NO_DEPTH))
|
||||
{
|
||||
float np_param[] = {
|
||||
c, e, -3.0F * ( fabsf( fabsf(w) - 0.6666667F ) - 0.33333334F ), w,
|
||||
};
|
||||
@ -1375,20 +1378,23 @@ int sampleBiomeNoise(const BiomeNoise *bn, int x, int y, int z, uint64_t *dat, i
|
||||
|
||||
//double py = y + sampleDoublePerlin(&bn->shift, y, z, x) * 4.0;
|
||||
d = 1.0 - (y << 2) / 128.0 - 83.0/160.0 + off;
|
||||
}
|
||||
|
||||
t = sampleDoublePerlin(&bn->temperature, px, 0, pz);
|
||||
h = sampleDoublePerlin(&bn->humidity, px, 0, pz);
|
||||
|
||||
int64_t np[] = {
|
||||
(int64_t)(10000.0F*t),
|
||||
(int64_t)(10000.0F*h),
|
||||
(int64_t)(10000.0F*c),
|
||||
(int64_t)(10000.0F*e),
|
||||
(int64_t)(10000.0F*d),
|
||||
(int64_t)(10000.0F*w),
|
||||
};
|
||||
int64_t l_np[6];
|
||||
int64_t *p_np = np ? np : l_np;
|
||||
p_np[0] = (int64_t)(10000.0F*t);
|
||||
p_np[1] = (int64_t)(10000.0F*h);
|
||||
p_np[2] = (int64_t)(10000.0F*c);
|
||||
p_np[3] = (int64_t)(10000.0F*e);
|
||||
p_np[4] = (int64_t)(10000.0F*d);
|
||||
p_np[5] = (int64_t)(10000.0F*w);
|
||||
|
||||
int id = p2overworld((const uint64_t*)np, dat);
|
||||
int id = none;
|
||||
if (!(flags & SAMPLE_NO_BIOME))
|
||||
id = p2overworld((const uint64_t*)p_np, dat);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -1396,6 +1402,8 @@ int sampleBiomeNoise(const BiomeNoise *bn, int x, int y, int z, uint64_t *dat, i
|
||||
static void genBiomeNoise3D(const BiomeNoise *bn, int *out, Range r, int opt)
|
||||
{
|
||||
uint64_t dat = 0;
|
||||
uint64_t *p_dat = opt ? &dat : NULL;
|
||||
uint32_t flags = opt ? SAMPLE_NO_SHIFT : 0;
|
||||
int i, j, k;
|
||||
int *p = out;
|
||||
int scale = r.scale > 4 ? r.scale / 4 : 1;
|
||||
@ -1409,7 +1417,7 @@ static void genBiomeNoise3D(const BiomeNoise *bn, int *out, Range r, int opt)
|
||||
for (i = 0; i < r.sx; i++)
|
||||
{
|
||||
int xi = (r.x+i)*scale + mid;
|
||||
*p = sampleBiomeNoise(bn, xi, yk, zj, opt ? &dat : NULL, opt);
|
||||
*p = sampleBiomeNoise(bn, NULL, xi, yk, zj, p_dat, flags);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
@ -1457,7 +1465,7 @@ int genBiomeNoiseScaled(const BiomeNoise *bn, int *out, Range r, int mc, uint64_
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = sampleBiomeNoise(bn, x4, y4, z4, 0, 0);
|
||||
*p = sampleBiomeNoise(bn, 0, x4, y4, z4, 0, 0);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
8
layers.h
8
layers.h
@ -436,9 +436,15 @@ int genEndScaled(const EndNoise *en, int *out, Range r, int mc, uint64_t sha);
|
||||
* The 1.18 End generation remains similar to 1.17 and does NOT use the
|
||||
* biome noise.
|
||||
*/
|
||||
enum {
|
||||
SAMPLE_NO_SHIFT = 0x1,
|
||||
SAMPLE_NO_DEPTH = 0x2,
|
||||
SAMPLE_NO_BIOME = 0x4,
|
||||
};
|
||||
void initBiomeNoise(BiomeNoise *bn, int mc);
|
||||
void setBiomeSeed(BiomeNoise *bn, uint64_t seed, int large);
|
||||
int sampleBiomeNoise(const BiomeNoise *bn, int x, int y, int z, uint64_t *dat, int approx);
|
||||
int sampleBiomeNoise(const BiomeNoise *bn, int64_t *np, int x, int y, int z,
|
||||
uint64_t *dat, uint32_t flags);
|
||||
/**
|
||||
* The scaled biome noise generation applies for the Overworld version 1.18.
|
||||
* The 'sha' hash of the seed is only required for voronoi at scale 1:1.
|
||||
|
21
tests.c
21
tests.c
@ -112,7 +112,7 @@ int testBiomeGen1x1(const int *mc, const uint32_t *expect, int dim, int bits, in
|
||||
fflush(stdout);
|
||||
|
||||
double t = -now();
|
||||
h = getRef(mc[test], dim, bits, spread, "t16");
|
||||
h = getRef(mc[test], dim, bits, spread, NULL);
|
||||
t += now();
|
||||
printf("got %08x %s\e[0m (%ld msec)\n",
|
||||
h, h == expect[test] ? "\e[1;92mOK" : "\e[1;91mFAILED",
|
||||
@ -158,6 +158,8 @@ uint32_t testAreas(int mc, int dim, int scale)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int testGeneration()
|
||||
{
|
||||
const int mc_vers[] = {
|
||||
@ -172,9 +174,20 @@ int testGeneration()
|
||||
};
|
||||
const int testcnt = sizeof(mc_vers) / sizeof(int);
|
||||
|
||||
printf("Testing 1x1 biome generation (quick):\n");
|
||||
if (!testBiomeGen1x1(mc_vers, b6_hashes, 0, 6, 1, 1))// testcnt))
|
||||
;//return -1;
|
||||
//printf("Testing 1x1 biome generation (quick):\n");
|
||||
//if (!testBiomeGen1x1(mc_vers, b6_hashes, 0, 6, 1, testcnt))
|
||||
// return -1;
|
||||
|
||||
Generator g;
|
||||
setupGenerator(&g, MC_1_18, 0);
|
||||
applySeed(&g, 0, 1234);
|
||||
Pos p = getSpawn(&g);
|
||||
printf("%d %d\n", p.x, p.z);
|
||||
|
||||
StrongholdIter sh;
|
||||
initFirstStronghold(&sh, g.mc, g.seed);
|
||||
while (nextStronghold(&sh, &g) > 0)
|
||||
printf("Stronghold #: (%6d, %6d)\n", sh.pos.x, sh.pos.z);
|
||||
|
||||
printf("Area generation tests:\n");
|
||||
testAreas(MC_1_18, 0, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user