Skip to content

Commit e49c8c5

Browse files
committed
Added Pale Garden biome and Small End Islands
* added pale_garden biome with 1.21.3 (version TBA) * added small end islands and better end surface generation (#117) * added linked end gateway finder (#117) * fixed inaccurate End generation at large distances from 0,0 * fixed incorrect biome in outer end rings * fixed incorrect biome area size (#122)
1 parent 0af31b4 commit e49c8c5

15 files changed

Lines changed: 3446 additions & 566 deletions

biomenoise.c

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ double sampleSurfaceNoiseBetween(const SurfaceNoise *sn, int x, int y, int z,
7474
dy = y * sy;
7575

7676
vmin += samplePerlin(&sn->octmin.octaves[i], dx, dy, dz, sy, dy) * amp;
77-
if (vmin - amp > noiseMax) return noiseMax;
7877
vmax += samplePerlin(&sn->octmax.octaves[i], dx, dy, dz, sy, dy) * amp;
79-
if (vmax + amp < noiseMin) return noiseMin;
78+
if (vmin - amp > noiseMax && vmax - amp > noiseMax)
79+
return noiseMax;
80+
if (vmin + amp < noiseMin && vmax + amp < noiseMin)
81+
return noiseMin;
8082

8183
amp *= 0.5;
8284
persist *= 2.0;
@@ -436,7 +438,10 @@ int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h)
436438
uint16_t v = 0;
437439
if (rsq > 4096 && sampleSimplex2D(&en->perlin, rx, rz) < -0.9f)
438440
{
439-
v = (llabs(rx) * 3439 + llabs(rz) * 147) % 13 + 9;
441+
//v = (llabs(rx) * 3439 + llabs(rz) * 147) % 13 + 9;
442+
v = (unsigned int)(
443+
fabsf((float)rx) * 3439.0f + fabsf((float)rz) * 147.0f
444+
) % 13 + 9;
440445
v *= v;
441446
}
442447
hmap[(int64_t)j*hw+i] = v;
@@ -457,12 +462,12 @@ int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h)
457462
{
458463
hx = 2*hx + 1;
459464
hz = 2*hz + 1;
460-
if (en->mc >= MC_1_14)
461-
{
465+
if (en->mc > MC_1_13)
466+
{ // add outer end rings
462467
rsq = hx * hx + hz * hz;
463468
if ((int)rsq < 0)
464469
{
465-
out[j*w+i] = small_end_islands;
470+
out[j*w+i] = end_barrens;
466471
continue;
467472
}
468473
}
@@ -529,7 +534,10 @@ float getEndHeightNoise(const EndNoise *en, int x, int z, int range)
529534
uint16_t v = 0;
530535
if (rsq > 4096 && sampleSimplex2D(&en->perlin, rx, rz) < -0.9f)
531536
{
532-
v = (llabs(rx) * 3439 + llabs(rz) * 147) % 13 + 9;
537+
//v = (llabs(rx) * 3439 + llabs(rz) * 147) % 13 + 9;
538+
v = (unsigned int)(
539+
fabsf((float)rx) * 3439.0f + fabsf((float)rz) * 147.0f
540+
) % 13 + 9;
533541
rx = (oddx - i * 2);
534542
rz = (oddz - j * 2);
535543
rsq = rx*rx + rz*rz;
@@ -546,28 +554,9 @@ float getEndHeightNoise(const EndNoise *en, int x, int z, int range)
546554
return ret;
547555
}
548556

549-
#define END_NOISE_COL_YMIN 2
550-
#define END_NOISE_COL_YMAX 18
551-
#define END_NOISE_COL_SIZE (END_NOISE_COL_YMAX - END_NOISE_COL_YMIN + 1)
552-
553-
void sampleNoiseColumnEnd(double column[], const SurfaceNoise *sn,
554-
const EndNoise *en, int x, int z, int colymin, int colymax)
555-
{
556-
double depth = getEndHeightNoise(en, x, z, 0) - 8.0f;
557-
int y;
558-
for (y = colymin; y <= colymax; y++)
559-
{
560-
double noise = sampleSurfaceNoise(sn, x, y, z);
561-
noise += depth; // falloff for the End is just the depth
562-
// clamp top and bottom slides from End settings
563-
noise = clampedLerp((32 + 46 - y) / 64.0, -3000, noise);
564-
noise = clampedLerp((y - 1) / 7.0, -30, noise);
565-
column[y - colymin] = noise;
566-
}
567-
}
568-
569-
void sampleNoiseColumnEndFull(double column[END_NOISE_COL_SIZE],
570-
const SurfaceNoise *sn, const EndNoise *en, int x, int z)
557+
void sampleNoiseColumnEnd(double column[],
558+
const SurfaceNoise *sn, const EndNoise *en, int x, int z,
559+
int colymin, int colymax)
571560
{
572561
// clamped (32 + 46 - y) / 64.0
573562
static const double upper_drop[] = {
@@ -583,9 +572,21 @@ void sampleNoiseColumnEndFull(double column[END_NOISE_COL_SIZE],
583572
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // 8-15
584573
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // 16-23
585574
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // 24-31
586-
1.0 // 32
575+
1.0, // 32
587576
};
588577

578+
int y;
579+
if (en->mc > MC_1_13)
580+
{ // add outer end rings
581+
uint64_t rsq = (uint64_t) x * x + (uint64_t) z * z;
582+
if ((int)rsq < 0)
583+
{
584+
for (y = colymin; y <= colymax; y++)
585+
column[y - colymin] = nan("");
586+
return;
587+
}
588+
}
589+
589590
// depth is between [-108, +72]
590591
// noise is between [-128, +128]
591592
// for a sold block we need the upper drop as:
@@ -595,23 +596,18 @@ void sampleNoiseColumnEndFull(double column[END_NOISE_COL_SIZE],
595596
// (72 + 128) * l - 30 * (1-l) > 0 => lower_drop = l > 3/23
596597
// which occurs at y = 3 for the lowest relevant noise cell
597598

598-
// in terms of the depth this becomes:
599-
// l > 30 / (103 + depth)
600-
601599
double depth = getEndHeightNoise(en, x, z, 0) - 8.0f;
602-
int y;
603-
for (y = END_NOISE_COL_YMIN; y <= END_NOISE_COL_YMAX; y++)
600+
for (y = colymin; y <= colymax; y++)
604601
{
605-
if (lower_drop[y] * (103.0 + depth) < 30)
606-
{
607-
column[y - END_NOISE_COL_YMIN] = -30;
602+
if (lower_drop[y] == 0.0) {
603+
column[y - colymin] = -30;
608604
continue;
609605
}
610-
double noise = sampleSurfaceNoiseBetween(sn, x, y, z, -128, 128);
606+
double noise = sampleSurfaceNoiseBetween(sn, x, y, z, -128, +128);
611607
double clamped = noise + depth;
612608
clamped = lerp(upper_drop[y], -3000, clamped);
613609
clamped = lerp(lower_drop[y], -30, clamped);
614-
column[y - END_NOISE_COL_YMIN] = clamped;
610+
column[y - colymin] = clamped;
615611
}
616612
}
617613

@@ -650,7 +646,7 @@ int getSurfaceHeight(
650646
return 0;
651647
}
652648

653-
int getSurfaceHeightEnd(int mc, uint64_t seed, int x, int z)
649+
int getEndSurfaceHeight(int mc, uint64_t seed, int x, int z)
654650
{
655651
EndNoise en;
656652
setEndSeed(&en, mc, seed);
@@ -678,28 +674,31 @@ int getSurfaceHeightEnd(int mc, uint64_t seed, int x, int z)
678674
return getSurfaceHeight(ncol00, ncol01, ncol10, ncol11, y0, y1, 4, dx, dz);
679675
}
680676

681-
int mapSurfaceHeightEnd(const EndNoise *en, const SurfaceNoise *sn, float *y,
682-
int x, int z, int w, int h, int scale)
677+
int mapEndSurfaceHeight(float *y, const EndNoise *en, const SurfaceNoise *sn,
678+
int x, int z, int w, int h, int scale, int ymin)
683679
{
684680
if (scale != 1 && scale != 2 && scale != 4 && scale != 8)
685681
return 1;
686682

687-
enum { YSIZ = END_NOISE_COL_SIZE };
688-
683+
int y0 = ymin >> 2;
684+
if (y0 < 2) y0 = 2;
685+
if (y0 > 17) y0 = 17;
686+
int y1 = 18;
687+
int yn = y1 - y0 + 1;
689688
double cellmid = scale > 1 ? scale / 16.0 : 0;
690689
int cellsiz = 8 / scale;
691690
int cx = floordiv(x, cellsiz);
692691
int cz = floordiv(z, cellsiz);
693692
int cw = floordiv(x + w - 1, cellsiz) - cx + 2;
694693
int i, j;
695694

696-
double *buf = malloc(sizeof(double) * YSIZ * cw * 2);
695+
double *buf = malloc(sizeof(double) * yn * cw * 2);
697696
double *ncol[2];
698697
ncol[0] = buf;
699-
ncol[1] = buf + YSIZ * cw;
698+
ncol[1] = buf + yn * cw;
700699

701700
for (i = 0; i < cw; i++)
702-
sampleNoiseColumnEndFull(ncol[1]+i*YSIZ, sn, en, cx+i, cz+0);
701+
sampleNoiseColumnEnd(ncol[1]+i*yn, sn, en, cx+i, cz+0, y0, y1);
703702

704703
for (j = 0; j < h; j++)
705704
{
@@ -711,7 +710,7 @@ int mapSurfaceHeightEnd(const EndNoise *en, const SurfaceNoise *sn, float *y,
711710
ncol[0] = ncol[1];
712711
ncol[1] = tmp;
713712
for (i = 0; i < cw; i++)
714-
sampleNoiseColumnEndFull(ncol[1]+i*YSIZ, sn, en, cx+i, cj+1);
713+
sampleNoiseColumnEnd(ncol[1]+i*yn, sn, en, cx+i, cj+1, y0, y1);
715714
}
716715

717716
for (i = 0; i < w; i++)
@@ -720,10 +719,10 @@ int mapSurfaceHeightEnd(const EndNoise *en, const SurfaceNoise *sn, float *y,
720719
int di = x + i - ci * cellsiz;
721720
double dx = di / (double) cellsiz + cellmid;
722721
double dz = dj / (double) cellsiz + cellmid;
723-
double *ncol0 = ncol[0] + (ci - cx) * YSIZ;
724-
double *ncol1 = ncol[1] + (ci - cx) * YSIZ;
725-
y[j*w+i] = getSurfaceHeight(ncol0, ncol1, ncol0+YSIZ, ncol1+YSIZ,
726-
END_NOISE_COL_YMIN, END_NOISE_COL_YMAX, 4, dx, dz);
722+
double *ncol0 = ncol[0] + (ci - cx) * yn;
723+
double *ncol1 = ncol[1] + (ci - cx) * yn;
724+
y[j*w+i] = getSurfaceHeight(ncol0, ncol1, ncol0+yn, ncol1+yn,
725+
y0, y1, 4, dx, dz);
727726
}
728727
}
729728

@@ -802,9 +801,9 @@ int genEndScaled(const EndNoise *en, int *out, Range r, int mc, uint64_t sha)
802801
out[j*r.sx+i] = the_end;
803802
continue;
804803
}
805-
else if (mc >= MC_1_14 && (int)(rsq) < 0)
804+
else if (mc > MC_1_13 && (int)(rsq) < 0)
806805
{
807-
out[j*r.sx+i] = small_end_islands;
806+
out[j*r.sx+i] = end_barrens;
808807
continue;
809808
}
810809
float h = getEndHeightNoise(en, hx, hz, 4);

biomenoise.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ extern BiomeTree g_btree[MC_NEWEST - MC_1_18 + 1];
175175
void initSurfaceNoise(SurfaceNoise *sn, int dim, uint64_t seed);
176176
void initSurfaceNoiseBeta(SurfaceNoiseBeta *snb, uint64_t seed);
177177
double sampleSurfaceNoise(const SurfaceNoise *sn, int x, int y, int z);
178+
double sampleSurfaceNoiseBetween(const SurfaceNoise *sn, int x, int y, int z,
179+
double noiseMin, double noiseMax);
178180

179181

180182
//==============================================================================
@@ -222,9 +224,9 @@ int genNetherScaled(const NetherNoise *nn, int *out, Range r, int mc, uint64_t s
222224
void setEndSeed(EndNoise *en, int mc, uint64_t seed);
223225
int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h);
224226
int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h);
225-
int getSurfaceHeightEnd(int mc, uint64_t seed, int x, int z);
226-
int mapSurfaceHeightEnd(const EndNoise *en, const SurfaceNoise *sn, float *y,
227-
int x, int z, int w, int h, int scale);
227+
int getEndSurfaceHeight(int mc, uint64_t seed, int x, int z);
228+
int mapEndSurfaceHeight(float *y, const EndNoise *en, const SurfaceNoise *sn,
229+
int x, int z, int w, int h, int scale, int ymin);
228230

229231
/**
230232
* The scaled End generation supports scales 1, 4, 16, and 64.
@@ -307,6 +309,8 @@ int genBiomeNoiseBetaScaled(const BiomeNoiseBeta *bnb, const SurfaceNoiseBeta *s
307309
int *out, Range r);
308310

309311

312+
int getBiomeDepthAndScale(int id, double *depth, double *scale, int *grass);
313+
310314
// Gets the range in the parent/source layer which may be accessed by voronoi.
311315
Range getVoronoiSrcRange(Range r);
312316

0 commit comments

Comments
 (0)