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;
case Mineshaft:
pos->x = (int)( ((uint32_t)regX << 4) );
pos->z = (int)( ((uint32_t)regZ << 4) );
return isMineshaftChunk(mc, seed, regX, regZ);
return getMineshafts(mc, seed, regX, regZ, regX, regZ, pos, 1);
case Fortress:
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;
setSeed(&s, seed);
uint64_t i = nextLong(&s);
uint64_t j = nextLong(&s);
setSeed(&s, chunkX * i ^ chunkZ * j ^ seed);
if (mc >= MC_1_13)
uint64_t a = nextLong(&s);
uint64_t b = nextLong(&s);
int i, j;
int n = 0;
for (i = cx0; i <= cx1; i++)
{
return nextDouble(&s) < 0.004;
}
else
{
int d = chunkX;
if (-chunkX > d) d = -chunkX;
if (+chunkZ > d) d = +chunkZ;
if (-chunkZ > d) d = -chunkZ;
skipNextN(&s, 1);
return nextDouble(&s) < 0.004 && nextInt(&s, 80) < d;
uint64_t aix = i * a ^ seed;
for (j = cz0; j <= cz1; j++)
{
setSeed(&s, aix ^ j * b);
if (mc >= MC_1_13)
{
if U(nextDouble(&s) < 0.004)
{
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
//==============================================================================

View File

@ -52,6 +52,7 @@ enum StructureType
Bastion,
End_City,
End_Gateway,
FEATURE_NUM
};
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))
Pos getLargeStructureChunkInRegion(StructureConfig config, uint64_t seed, int regX, int regZ);
/* Some structures check each chunk individually for viability.
* The placement and biome check within a valid chunk is at block position (9,9)
* or at (2,2) with layer scale=4 from 1.16 onwards.
/* Checks a chunk area, starting at (chunkX, chunkZ) with size (chunkW, chunkH)
* for Mineshaft positions. If not NULL, positions are written to the buffer
* '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
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
* generating caves, ravines, mineshafts, and virtually all other structures.
*/
inline static int64_t chunkGenerateRnd(const uint64_t worldSeed,
const int chunkX, const int chunkZ)
inline static
uint64_t chunkGenerateRnd(uint64_t worldSeed, int chunkX, int chunkZ)
{
uint64_t rnd;
setSeed(&rnd, worldSeed);

View File

@ -37,7 +37,7 @@ static void setupScale(Layer *l, int scale)
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));
Layer *p;
@ -144,8 +144,8 @@ static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
if (largeBiomes)
{
p = setupLayer(g, L_ZOOM_LARGE_BIOME_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_A, mapZoom, mc, 2, 3, 1004, 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);
@ -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_8_RIVER, mapZoom, mc, 2, 3, 1002, 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_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_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);
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);
if (largeBiomes)
{
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);
}
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
* 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,
// largeBiomes layers
L_ZOOM_LARGE_BIOME_A,
L_ZOOM_LARGE_BIOME_B,
L_ZOOM_LARGE_A,
L_ZOOM_LARGE_B,
L_ZOOM_L_RIVER_A,
L_ZOOM_L_RIVER_B,
L_NUM
};
@ -95,7 +97,7 @@ extern "C"
void setupGenerator(LayerStack *g, int mc);
/* 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

View File

@ -2712,7 +2712,7 @@ int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
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)
{
uint64_t s = sha;