fixes for large biomes + more efficient mineshaft finder

This commit is contained in:
Cubitect 2021-07-18 11:48:54 +02:00
parent 3b65b4bbf7
commit 61a341e1f6
5 changed files with 89 additions and 41 deletions

View File

@ -223,9 +223,7 @@ int getStructurePos(int structureType, int mc, uint64_t seed, int regX, int regZ
return nextFloat(&seed) < 0.01; return nextFloat(&seed) < 0.01;
case Mineshaft: case Mineshaft:
pos->x = (int)( ((uint32_t)regX << 4) ); return getMineshafts(mc, seed, regX, regZ, regX, regZ, pos, 1);
pos->z = (int)( ((uint32_t)regZ << 4) );
return isMineshaftChunk(mc, seed, regX, regZ);
case Fortress: case Fortress:
if (mc < MC_1_16) { if (mc < MC_1_16) {
@ -262,29 +260,64 @@ int getStructurePos(int structureType, int mc, uint64_t seed, int regX, int regZ
} }
int isMineshaftChunk(int mc, uint64_t seed, int chunkX, int chunkZ) int getMineshafts(int mc, uint64_t seed, int cx0, int cz0, int cx1, int cz1,
Pos *out, int nout)
{ {
uint64_t s; uint64_t s;
setSeed(&s, seed); setSeed(&s, seed);
uint64_t i = nextLong(&s); uint64_t a = nextLong(&s);
uint64_t j = nextLong(&s); uint64_t b = nextLong(&s);
setSeed(&s, chunkX * i ^ chunkZ * j ^ seed); int i, j;
if (mc >= MC_1_13) int n = 0;
for (i = cx0; i <= cx1; i++)
{ {
return nextDouble(&s) < 0.004; uint64_t aix = i * a ^ seed;
}
else for (j = cz0; j <= cz1; j++)
{ {
int d = chunkX; setSeed(&s, aix ^ j * b);
if (-chunkX > d) d = -chunkX;
if (+chunkZ > d) d = +chunkZ; if (mc >= MC_1_13)
if (-chunkZ > d) d = -chunkZ; {
skipNextN(&s, 1); if U(nextDouble(&s) < 0.004)
return nextDouble(&s) < 0.004 && nextInt(&s, 80) < d; {
if (out && n < nout)
{
out[n].x = (int)((uint32_t)i << 4);
out[n].z = (int)((uint32_t)j << 4);
}
n++;
}
}
else
{
skipNextN(&s, 1);
if U(nextDouble(&s) < 0.004)
{
int d = i;
if (-i > d) d = -i;
if (+j > d) d = +j;
if (-j > d) d = -j;
if (d >= 80 || nextInt(&s, 80) < d)
{
if (out && n < nout)
{
out[n].x = (int)((uint32_t)i << 4);
out[n].z = (int)((uint32_t)j << 4);
}
n++;
}
}
}
}
} }
return n;
} }
//============================================================================== //==============================================================================
// Multi-Structure Checks // Multi-Structure Checks
//============================================================================== //==============================================================================

View File

@ -52,6 +52,7 @@ enum StructureType
Bastion, Bastion,
End_City, End_City,
End_Gateway, End_Gateway,
FEATURE_NUM
}; };
enum // village house types prior to 1.14 enum // village house types prior to 1.14
@ -323,11 +324,13 @@ Pos getLargeStructurePos(StructureConfig config, uint64_t seed, int regX, int re
static inline __attribute__((const)) static inline __attribute__((const))
Pos getLargeStructureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ); Pos getLargeStructureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ);
/* Some structures check each chunk individually for viability. /* Checks a chunk area, starting at (chunkX, chunkZ) with size (chunkW, chunkH)
* The placement and biome check within a valid chunk is at block position (9,9) * for Mineshaft positions. If not NULL, positions are written to the buffer
* or at (2,2) with layer scale=4 from 1.16 onwards. * 'out' up to a maximum number of 'nout'. The return value is the number of
* chunks with Mineshafts in the area.
*/ */
int isMineshaftChunk(int mc, uint64_t seed, int chunkX, int chunkZ); int getMineshafts(int mc, uint64_t seed, int chunkX, int chunkZ,
int chunkW, int chunkH, Pos *out, int nout);
// not exacly a structure // not exacly a structure
static inline __attribute__((const)) static inline __attribute__((const))
@ -668,8 +671,8 @@ int isViableEndCityTerrain(const EndNoise *en, const SurfaceNoise *sn,
* This random object is used for recursiveGenerate() which is responsible for * This random object is used for recursiveGenerate() which is responsible for
* generating caves, ravines, mineshafts, and virtually all other structures. * generating caves, ravines, mineshafts, and virtually all other structures.
*/ */
inline static int64_t chunkGenerateRnd(const uint64_t worldSeed, inline static
const int chunkX, const int chunkZ) uint64_t chunkGenerateRnd(uint64_t worldSeed, int chunkX, int chunkZ)
{ {
uint64_t rnd; uint64_t rnd;
setSeed(&rnd, worldSeed); setSeed(&rnd, worldSeed);

View File

@ -37,7 +37,7 @@ static void setupScale(Layer *l, int scale)
setupScale(l->p2, scale * l->zoom); setupScale(l->p2, scale * l->zoom);
} }
static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes) void setupGeneratorLargeBiomes(LayerStack *g, int mc, int largeBiomes)
{ {
memset(g, 0, sizeof(LayerStack)); memset(g, 0, sizeof(LayerStack));
Layer *p; Layer *p;
@ -144,8 +144,8 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
if (largeBiomes) if (largeBiomes)
{ {
p = setupLayer(g, L_ZOOM_LARGE_BIOME_A, mapZoom, mc, 2, 3, 1004, p, 0); p = setupLayer(g, L_ZOOM_LARGE_A, mapZoom, mc, 2, 3, 1004, p, 0);
p = setupLayer(g, L_ZOOM_LARGE_BIOME_B, mapZoom, mc, 2, 3, 1005, p, 0); p = setupLayer(g, L_ZOOM_LARGE_B, mapZoom, mc, 2, 3, 1005, p, 0);
} }
p = setupLayer(g, L_SMOOTH_4, mapSmooth, mc, 1, 2, 1000, p, 0); p = setupLayer(g, L_SMOOTH_4, mapSmooth, mc, 1, 2, 1000, p, 0);
@ -158,6 +158,13 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
p = setupLayer(g, L_ZOOM_16_RIVER, mapZoom, mc, 2, 3, 1001, p, 0); p = setupLayer(g, L_ZOOM_16_RIVER, mapZoom, mc, 2, 3, 1001, p, 0);
p = setupLayer(g, L_ZOOM_8_RIVER, mapZoom, mc, 2, 3, 1002, p, 0); p = setupLayer(g, L_ZOOM_8_RIVER, mapZoom, mc, 2, 3, 1002, p, 0);
p = setupLayer(g, L_ZOOM_4_RIVER, mapZoom, mc, 2, 3, 1003, p, 0); p = setupLayer(g, L_ZOOM_4_RIVER, mapZoom, mc, 2, 3, 1003, p, 0);
if (largeBiomes)
{
p = setupLayer(g, L_ZOOM_L_RIVER_A, mapZoom, mc, 2, 3, 1004, p, 0);
p = setupLayer(g, L_ZOOM_L_RIVER_B, mapZoom, mc, 2, 3, 1005, p, 0);
}
p = setupLayer(g, L_RIVER_4, mapRiver, mc, 1, 2, 1, p, 0); p = setupLayer(g, L_RIVER_4, mapRiver, mc, 1, 2, 1, p, 0);
p = setupLayer(g, L_SMOOTH_4_RIVER, mapSmooth, mc, 1, 2, 1000, p, 0); p = setupLayer(g, L_SMOOTH_4_RIVER, mapSmooth, mc, 1, 2, 1000, p, 0);
} }
@ -192,23 +199,26 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
g->entry_1 = p; g->entry_1 = p;
g->entry_4 = g->layers + (mc <= MC_1_12 ? L_RIVER_MIX_4 : L_OCEAN_MIX_4); g->entry_4 = g->layers + (mc <= MC_1_12 ? L_RIVER_MIX_4 : L_OCEAN_MIX_4);
g->entry_16 = g->layers + (mc <= MC_1_6 ? L_SWAMP_RIVER_16 : L_SHORE_16); if (largeBiomes)
g->entry_64 = g->layers + (mc <= MC_1_7 ? L_HILLS_64 : L_SUNFLOWER_64); {
g->entry_256 = g->layers + (mc <= MC_1_14 ? L_BIOME_256 : L_BAMBOO_256); g->entry_16 = g->layers + L_ZOOM_4;
g->entry_64 = g->layers + (mc <= MC_1_6 ? L_SWAMP_RIVER_16 : L_SHORE_16);
g->entry_256 = g->layers + (mc <= MC_1_7 ? L_HILLS_64 : L_SUNFLOWER_64);
}
else
{
g->entry_16 = g->layers + (mc <= MC_1_6 ? L_SWAMP_RIVER_16 : L_SHORE_16);
g->entry_64 = g->layers + (mc <= MC_1_7 ? L_HILLS_64 : L_SUNFLOWER_64);
g->entry_256 = g->layers + (mc <= MC_1_14 ? L_BIOME_256 : L_BAMBOO_256);
}
setupScale(g->entry_1, 1); setupScale(g->entry_1, 1);
} }
void setupGenerator(LayerStack *g, int mc) void setupGenerator(LayerStack *g, int mc)
{ {
setupGeneratorImpl(g, mc, 0); setupGeneratorLargeBiomes(g, mc, 0);
} }
void setupLargeBiomesGenerator(LayerStack *g, int mc)
{
setupGeneratorImpl(g, mc, 1);
}
/* Recursively calculates the minimum buffer size required to generate an area /* Recursively calculates the minimum buffer size required to generate an area
* of the specified size from the current layer onwards. * of the specified size from the current layer onwards.
*/ */

View File

@ -66,8 +66,10 @@ enum
L_VORONOI_1, L_VORONOI_ZOOM_1 = L_VORONOI_1, L_VORONOI_1, L_VORONOI_ZOOM_1 = L_VORONOI_1,
// largeBiomes layers // largeBiomes layers
L_ZOOM_LARGE_BIOME_A, L_ZOOM_LARGE_A,
L_ZOOM_LARGE_BIOME_B, L_ZOOM_LARGE_B,
L_ZOOM_L_RIVER_A,
L_ZOOM_L_RIVER_B,
L_NUM L_NUM
}; };
@ -95,7 +97,7 @@ extern "C"
void setupGenerator(LayerStack *g, int mc); void setupGenerator(LayerStack *g, int mc);
/* Initialise an instance of a generator with largeBiomes configuration. */ /* Initialise an instance of a generator with largeBiomes configuration. */
void setupLargeBiomesGenerator(LayerStack *g, int mc); void setupGeneratorLargeBiomes(LayerStack *g, int mc, int largeBiomes);
/* Calculates the minimum size of the buffers required to generate an area of /* Calculates the minimum size of the buffers required to generate an area of

View File

@ -2712,7 +2712,7 @@ int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
return 0; return 0;
} }
static inline void getVoronoiCell(int64_t sha, int a, int b, int c, static inline void getVoronoiCell(uint64_t sha, int a, int b, int c,
int *x, int *y, int *z) int *x, int *y, int *z)
{ {
uint64_t s = sha; uint64_t s = sha;