mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-24 04:03:39 -04:00
Somewhat major changes to structure and layer functions.
1) Redone structure validation for 1.16 and for bug fixes. 2) Layer generation was reworked for performace.
This commit is contained in:
parent
b26f4eb1f7
commit
cf85da7159
@ -23,7 +23,8 @@ static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
|
|||||||
int w = 2*info.range, h = 2*info.range;
|
int w = 2*info.range, h = 2*info.range;
|
||||||
int64_t s;
|
int64_t s;
|
||||||
|
|
||||||
LayerStack g = setupGenerator(MC_1_14);
|
int mcversion = MC_1_14;
|
||||||
|
LayerStack g = setupGenerator(mcversion);
|
||||||
int *cache = allocCache(&g.layers[L_VORONOI_ZOOM_1], w, h);
|
int *cache = allocCache(&g.layers[L_VORONOI_ZOOM_1], w, h);
|
||||||
|
|
||||||
for (s = info.seedStart; s != info.seedEnd; s++)
|
for (s = info.seedStart; s != info.seedEnd; s++)
|
||||||
@ -40,7 +41,7 @@ static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
|
|||||||
{
|
{
|
||||||
Pos p;
|
Pos p;
|
||||||
p = getStructurePos(SWAMP_HUT_CONFIG, s, x, z);
|
p = getStructurePos(SWAMP_HUT_CONFIG, s, x, z);
|
||||||
if (isViableFeaturePos(Swamp_Hut, g, cache, p.x, p.z))
|
if (isViableStructurePos(SWAMP_HUT_CONFIG, mcversion, &g, s, p.x, p.z))
|
||||||
goto L_hut_found;
|
goto L_hut_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,7 +57,7 @@ static DWORD WINAPI searchCompactBiomesThread(LPVOID data)
|
|||||||
{
|
{
|
||||||
Pos p;
|
Pos p;
|
||||||
p = getLargeStructurePos(MONUMENT_CONFIG, s, x, z);
|
p = getLargeStructurePos(MONUMENT_CONFIG, s, x, z);
|
||||||
if (isViableOceanMonumentPos(g, cache, p.x, p.z))
|
if (isViableStructurePos(MONUMENT_CONFIG, mcversion, &g, s, p.x, p.z))
|
||||||
goto L_monument_found;
|
goto L_monument_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ int main(int argc, char *argv[])
|
|||||||
int regPosX = 0;
|
int regPosX = 0;
|
||||||
int regPosZ = 0;
|
int regPosZ = 0;
|
||||||
|
|
||||||
int mcversion = 0;
|
int mcversion = MC_1_16;
|
||||||
const char *seedFileName;
|
const char *seedFileName;
|
||||||
StructureConfig featureConfig;
|
StructureConfig featureConfig;
|
||||||
|
|
||||||
@ -35,14 +35,25 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc > 3)
|
if (argc > 3)
|
||||||
{
|
{
|
||||||
if (sscanf(argv[3], "%d", &mcversion) != 1) mcversion = 0;
|
int mcarg1 = 0, mcarg2 = 0;
|
||||||
|
int ac = sscanf(argv[3], "%d.%d", &mcarg1, &mcarg2);
|
||||||
|
if (ac < 1)
|
||||||
|
{
|
||||||
|
printf("Bad version format\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (ac > 1)
|
||||||
|
mcarg1 = 100 * mcarg1 + mcarg2;
|
||||||
|
if (mcarg1 < 113)
|
||||||
|
mcversion = MC_1_7;
|
||||||
|
else if (mcarg1 < 116)
|
||||||
|
mcversion = MC_1_13;
|
||||||
|
else
|
||||||
|
mcversion = MC_1_16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("MC version not specified. Set using 'mcversion' argument:\n"
|
printf("MC version not specified. Defaulting to 1.16\n");
|
||||||
"17 for MC1.7 - MC1.12\n113 for MC1.13+\n"
|
|
||||||
"Defaulting to MC 1.7.\n\n");
|
|
||||||
mcversion = 17;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -55,7 +66,7 @@ int main(int argc, char *argv[])
|
|||||||
regPosX -= 1;
|
regPosX -= 1;
|
||||||
regPosZ -= 1;
|
regPosZ -= 1;
|
||||||
|
|
||||||
if (mcversion >= 113)
|
if (mcversion >= MC_1_13)
|
||||||
{
|
{
|
||||||
featureConfig = SWAMP_HUT_CONFIG;
|
featureConfig = SWAMP_HUT_CONFIG;
|
||||||
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
|
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
|
||||||
@ -186,11 +197,10 @@ int main(int argc, char *argv[])
|
|||||||
if (biomeCache[0] != swamp)
|
if (biomeCache[0] != swamp)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
applySeed(&g, seed);
|
if (!isViableStructurePos(SWAMP_HUT_CONFIG, mcversion, &g, seed, qhpos[0].x, qhpos[0].z)) continue;
|
||||||
if (getBiomeAtPos(g, qhpos[0]) != swamp) continue;
|
if (!isViableStructurePos(SWAMP_HUT_CONFIG, mcversion, &g, seed, qhpos[1].x, qhpos[1].z)) continue;
|
||||||
if (getBiomeAtPos(g, qhpos[1]) != swamp) continue;
|
if (!isViableStructurePos(SWAMP_HUT_CONFIG, mcversion, &g, seed, qhpos[2].x, qhpos[2].z)) continue;
|
||||||
if (getBiomeAtPos(g, qhpos[2]) != swamp) continue;
|
if (!isViableStructurePos(SWAMP_HUT_CONFIG, mcversion, &g, seed, qhpos[3].x, qhpos[3].z)) continue;
|
||||||
if (getBiomeAtPos(g, qhpos[3]) != swamp) continue;
|
|
||||||
|
|
||||||
printf("%" PRId64 "\n", seed);
|
printf("%" PRId64 "\n", seed);
|
||||||
hits++;
|
hits++;
|
||||||
|
616
finders.c
616
finders.c
@ -100,10 +100,10 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt)
|
|||||||
int isQuadFeatureBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
int isQuadFeatureBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
||||||
{
|
{
|
||||||
// seed offsets for the regions (0,0) to (1,1)
|
// seed offsets for the regions (0,0) to (1,1)
|
||||||
const int64_t reg00base = sconf.seed;
|
const int64_t reg00base = sconf.salt;
|
||||||
const int64_t reg01base = 341873128712 + sconf.seed;
|
const int64_t reg01base = 341873128712 + sconf.salt;
|
||||||
const int64_t reg10base = 132897987541 + sconf.seed;
|
const int64_t reg10base = 132897987541 + sconf.salt;
|
||||||
const int64_t reg11base = 341873128712 + 132897987541 + sconf.seed;
|
const int64_t reg11base = 341873128712 + 132897987541 + sconf.salt;
|
||||||
|
|
||||||
const int range = sconf.chunkRange;
|
const int range = sconf.chunkRange;
|
||||||
const int upper = range - qual - 1;
|
const int upper = range - qual - 1;
|
||||||
@ -141,10 +141,10 @@ int isQuadFeatureBase(const StructureConfig sconf, const int64_t seed, const int
|
|||||||
|
|
||||||
void checkVec4QuadBases(const StructureConfig sconf, int64_t seeds[256])
|
void checkVec4QuadBases(const StructureConfig sconf, int64_t seeds[256])
|
||||||
{
|
{
|
||||||
const int64_t reg00base = sconf.seed;
|
const int64_t reg00base = sconf.salt;
|
||||||
const int64_t reg01base = 341873128712 + sconf.seed;
|
const int64_t reg01base = 341873128712 + sconf.salt;
|
||||||
const int64_t reg10base = 132897987541 + sconf.seed;
|
const int64_t reg10base = 132897987541 + sconf.salt;
|
||||||
const int64_t reg11base = 341873128712 + 132897987541 + sconf.seed;
|
const int64_t reg11base = 341873128712 + 132897987541 + sconf.salt;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@ -204,10 +204,10 @@ void checkVec4QuadBases(const StructureConfig sconf, int64_t seeds[256])
|
|||||||
int isTriFeatureBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
int isTriFeatureBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
||||||
{
|
{
|
||||||
// seed offsets for the regions (0,0) to (1,1)
|
// seed offsets for the regions (0,0) to (1,1)
|
||||||
const int64_t reg00base = sconf.seed;
|
const int64_t reg00base = sconf.salt;
|
||||||
const int64_t reg01base = 341873128712 + sconf.seed;
|
const int64_t reg01base = 341873128712 + sconf.salt;
|
||||||
const int64_t reg10base = 132897987541 + sconf.seed;
|
const int64_t reg10base = 132897987541 + sconf.salt;
|
||||||
const int64_t reg11base = 341873128712 + 132897987541 + sconf.seed;
|
const int64_t reg11base = 341873128712 + 132897987541 + sconf.salt;
|
||||||
|
|
||||||
const int range = sconf.chunkRange;
|
const int range = sconf.chunkRange;
|
||||||
const int upper = range - qual - 1;
|
const int upper = range - qual - 1;
|
||||||
@ -257,10 +257,10 @@ int isTriFeatureBase(const StructureConfig sconf, const int64_t seed, const int
|
|||||||
int isLargeQuadBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
int isLargeQuadBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
||||||
{
|
{
|
||||||
// seed offsets for the regions (0,0) to (1,1)
|
// seed offsets for the regions (0,0) to (1,1)
|
||||||
const int64_t reg00base = sconf.seed;
|
const int64_t reg00base = sconf.salt;
|
||||||
const int64_t reg01base = 341873128712 + sconf.seed;
|
const int64_t reg01base = 341873128712 + sconf.salt;
|
||||||
const int64_t reg10base = 132897987541 + sconf.seed;
|
const int64_t reg10base = 132897987541 + sconf.salt;
|
||||||
const int64_t reg11base = 341873128712 + 132897987541 + sconf.seed;
|
const int64_t reg11base = 341873128712 + 132897987541 + sconf.salt;
|
||||||
|
|
||||||
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
|
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
|
||||||
const int range = sconf.chunkRange;
|
const int range = sconf.chunkRange;
|
||||||
@ -334,10 +334,10 @@ int isLargeQuadBase(const StructureConfig sconf, const int64_t seed, const int q
|
|||||||
int isLargeTriBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
int isLargeTriBase(const StructureConfig sconf, const int64_t seed, const int qual)
|
||||||
{
|
{
|
||||||
// seed offsets for the regions (0,0) to (1,1)
|
// seed offsets for the regions (0,0) to (1,1)
|
||||||
const int64_t reg00base = sconf.seed;
|
const int64_t reg00base = sconf.salt;
|
||||||
const int64_t reg01base = 341873128712 + sconf.seed;
|
const int64_t reg01base = 341873128712 + sconf.salt;
|
||||||
const int64_t reg10base = 132897987541 + sconf.seed;
|
const int64_t reg10base = 132897987541 + sconf.salt;
|
||||||
const int64_t reg11base = 341873128712 + 132897987541 + sconf.seed;
|
const int64_t reg11base = 341873128712 + 132897987541 + sconf.salt;
|
||||||
|
|
||||||
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
|
// p1 = nextInt(range); p2 = nextInt(range); pos = (p1+p2)>>1
|
||||||
const int range = sconf.chunkRange;
|
const int range = sconf.chunkRange;
|
||||||
@ -577,7 +577,7 @@ static DWORD WINAPI search4QuadBasesThread(LPVOID data)
|
|||||||
lowerBitsCnt = sizeof(lowerBaseBitsQ1) / sizeof(lowerBaseBitsQ1[0]);
|
lowerBitsCnt = sizeof(lowerBaseBitsQ1) / sizeof(lowerBaseBitsQ1[0]);
|
||||||
for (i = 0; i < lowerBitsCnt; i++)
|
for (i = 0; i < lowerBitsCnt; i++)
|
||||||
{
|
{
|
||||||
lowerBits[i] = (lowerBaseBitsQ1[i] - stc.seed) & 0xffff;
|
lowerBits[i] = (lowerBaseBitsQ1[i] - stc.salt) & 0xffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stc.properties == 0 && stc.chunkRange == 24 && info.quality == 2)
|
else if (stc.properties == 0 && stc.chunkRange == 24 && info.quality == 2)
|
||||||
@ -585,7 +585,7 @@ static DWORD WINAPI search4QuadBasesThread(LPVOID data)
|
|||||||
lowerBitsCnt = sizeof(lowerBaseBitsQ2) / sizeof(lowerBaseBitsQ2[0]);
|
lowerBitsCnt = sizeof(lowerBaseBitsQ2) / sizeof(lowerBaseBitsQ2[0]);
|
||||||
for (i = 0; i < lowerBitsCnt; i++)
|
for (i = 0; i < lowerBitsCnt; i++)
|
||||||
{
|
{
|
||||||
lowerBits[i] = (lowerBaseBitsQ2[i] - stc.seed) & 0xffff;
|
lowerBits[i] = (lowerBaseBitsQ2[i] - stc.salt) & 0xffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (stc.properties == 0 && stc.chunkRange == 24 && info.quality == -1)
|
else if (stc.properties == 0 && stc.chunkRange == 24 && info.quality == -1)
|
||||||
@ -794,7 +794,7 @@ Pos getStructurePos(const StructureConfig config, int64_t seed,
|
|||||||
Pos pos;
|
Pos pos;
|
||||||
|
|
||||||
// set seed
|
// set seed
|
||||||
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.seed;
|
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.salt;
|
||||||
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
||||||
|
|
||||||
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
||||||
@ -836,7 +836,7 @@ Pos getStructureChunkInRegion(const StructureConfig config, int64_t seed,
|
|||||||
*/
|
*/
|
||||||
Pos pos;
|
Pos pos;
|
||||||
|
|
||||||
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.seed;
|
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.salt;
|
||||||
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
||||||
|
|
||||||
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
||||||
@ -869,7 +869,7 @@ Pos getLargeStructurePos(StructureConfig config, int64_t seed,
|
|||||||
//TODO: power of two chunk ranges...
|
//TODO: power of two chunk ranges...
|
||||||
|
|
||||||
// set seed
|
// set seed
|
||||||
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.seed;
|
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.salt;
|
||||||
seed = (seed ^ 0x5deece66dLL) & ((1LL << 48) - 1);
|
seed = (seed ^ 0x5deece66dLL) & ((1LL << 48) - 1);
|
||||||
|
|
||||||
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
||||||
@ -898,7 +898,7 @@ Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed,
|
|||||||
//TODO: power of two chunk ranges...
|
//TODO: power of two chunk ranges...
|
||||||
|
|
||||||
// set seed
|
// set seed
|
||||||
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.seed;
|
seed = regionX*341873128712 + regionZ*132897987541 + seed + config.salt;
|
||||||
seed = (seed ^ 0x5deece66dLL) & ((1LL << 48) - 1);
|
seed = (seed ^ 0x5deece66dLL) & ((1LL << 48) - 1);
|
||||||
|
|
||||||
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
||||||
@ -931,7 +931,7 @@ int isMineshaftChunk(int64_t seed, const int chunkX, const int chunkZ)
|
|||||||
|
|
||||||
int isTreasureChunk(int64_t seed, const int chunkX, const int chunkZ)
|
int isTreasureChunk(int64_t seed, const int chunkX, const int chunkZ)
|
||||||
{
|
{
|
||||||
seed = chunkX*341873128712 + chunkZ*132897987541 + seed + TREASURE_CONFIG.seed;
|
seed = chunkX*341873128712 + chunkZ*132897987541 + seed + TREASURE_CONFIG.salt;
|
||||||
setSeed(&seed);
|
setSeed(&seed);
|
||||||
return nextFloat(&seed) < 0.01;
|
return nextFloat(&seed) < 0.01;
|
||||||
}
|
}
|
||||||
@ -953,12 +953,12 @@ int getBiomeAtPos(const LayerStack g, const Pos pos)
|
|||||||
|
|
||||||
Pos findBiomePosition(
|
Pos findBiomePosition(
|
||||||
const int mcversion,
|
const int mcversion,
|
||||||
const LayerStack g,
|
const Layer *l,
|
||||||
int *cache,
|
int *cache,
|
||||||
const int centerX,
|
const int centerX,
|
||||||
const int centerZ,
|
const int centerZ,
|
||||||
const int range,
|
const int range,
|
||||||
const int *isValid,
|
const char *isValid,
|
||||||
int64_t *seed,
|
int64_t *seed,
|
||||||
int *passes
|
int *passes
|
||||||
)
|
)
|
||||||
@ -972,18 +972,17 @@ Pos findBiomePosition(
|
|||||||
int *map;
|
int *map;
|
||||||
int i, j, found;
|
int i, j, found;
|
||||||
|
|
||||||
Layer *layer = &g.layers[L_RIVER_MIX_4];
|
|
||||||
Pos out;
|
Pos out;
|
||||||
|
|
||||||
if (layer->scale != 4)
|
if (l->scale != 4)
|
||||||
{
|
{
|
||||||
printf("WARN findBiomePosition: The generator has unexpected scale %d at layer %d.\n",
|
printf("WARN findBiomePosition: require scale = 4, but have %d.\n",
|
||||||
layer->scale, L_RIVER_MIX_4);
|
l->scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
map = cache ? cache : allocCache(layer, width, height);
|
map = cache ? cache : allocCache(l, width, height);
|
||||||
|
|
||||||
genArea(layer, map, x1, z1, width, height);
|
genArea(l, map, x1, z1, width, height);
|
||||||
|
|
||||||
out.x = centerX;
|
out.x = centerX;
|
||||||
out.z = centerZ;
|
out.z = centerZ;
|
||||||
@ -1033,12 +1032,12 @@ Pos findBiomePosition(
|
|||||||
|
|
||||||
|
|
||||||
int areBiomesViable(
|
int areBiomesViable(
|
||||||
const LayerStack g,
|
const Layer * l,
|
||||||
int * cache,
|
int * cache,
|
||||||
const int posX,
|
const int posX,
|
||||||
const int posZ,
|
const int posZ,
|
||||||
const int radius,
|
const int radius,
|
||||||
const int * isValid
|
const char * isValid
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int x1 = (posX - radius) >> 2;
|
int x1 = (posX - radius) >> 2;
|
||||||
@ -1050,16 +1049,14 @@ int areBiomesViable(
|
|||||||
int i;
|
int i;
|
||||||
int *map;
|
int *map;
|
||||||
|
|
||||||
Layer *layer = &g.layers[L_RIVER_MIX_4];
|
if (l->scale != 4)
|
||||||
|
|
||||||
if (layer->scale != 4)
|
|
||||||
{
|
{
|
||||||
printf("WARN areBiomesViable: The generator has unexpected scale %d at layer %d.\n",
|
printf("WARN areBiomesViable: require scale = 4, but have %d.\n",
|
||||||
layer->scale, L_RIVER_MIX_4);
|
l->scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
map = cache ? cache : allocCache(layer, width, height);
|
map = cache ? cache : allocCache(l, width, height);
|
||||||
genArea(layer, map, x1, z1, width, height);
|
genArea(l, map, x1, z1, width, height);
|
||||||
|
|
||||||
for (i = 0; i < width*height; i++)
|
for (i = 0; i < width*height; i++)
|
||||||
{
|
{
|
||||||
@ -1121,9 +1118,9 @@ int getBiomeRadius(
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
|
||||||
int* getValidStrongholdBiomes()
|
const char* getValidStrongholdBiomes()
|
||||||
{
|
{
|
||||||
static int validStrongholdBiomes[256];
|
static char validStrongholdBiomes[256];
|
||||||
|
|
||||||
if (!validStrongholdBiomes[plains])
|
if (!validStrongholdBiomes[plains])
|
||||||
{
|
{
|
||||||
@ -1139,10 +1136,10 @@ int* getValidStrongholdBiomes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int findStrongholds(const int mcversion, LayerStack *g, int *cache,
|
int findStrongholds(const int mcversion, const LayerStack *g, int *cache,
|
||||||
Pos *locations, int64_t worldSeed, int maxSH, const int maxRadius)
|
Pos *locations, int64_t worldSeed, int maxSH, const int maxRadius)
|
||||||
{
|
{
|
||||||
const int *validStrongholdBiomes = getValidStrongholdBiomes();
|
const char *validStrongholdBiomes = getValidStrongholdBiomes();
|
||||||
int i, x, z;
|
int i, x, z;
|
||||||
double distance;
|
double distance;
|
||||||
|
|
||||||
@ -1153,6 +1150,8 @@ int findStrongholds(const int mcversion, LayerStack *g, int *cache,
|
|||||||
setSeed(&worldSeed);
|
setSeed(&worldSeed);
|
||||||
double angle = nextDouble(&worldSeed) * PI * 2.0;
|
double angle = nextDouble(&worldSeed) * PI * 2.0;
|
||||||
|
|
||||||
|
const Layer *l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
|
||||||
if (mcversion >= MC_1_9)
|
if (mcversion >= MC_1_9)
|
||||||
{
|
{
|
||||||
if (maxSH <= 0) maxSH = 128;
|
if (maxSH <= 0) maxSH = 128;
|
||||||
@ -1168,7 +1167,7 @@ int findStrongholds(const int mcversion, LayerStack *g, int *cache,
|
|||||||
x = (int)round(cos(angle) * distance);
|
x = (int)round(cos(angle) * distance);
|
||||||
z = (int)round(sin(angle) * distance);
|
z = (int)round(sin(angle) * distance);
|
||||||
|
|
||||||
locations[i] = findBiomePosition(mcversion, *g, cache,
|
locations[i] = findBiomePosition(mcversion, l, cache,
|
||||||
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
||||||
&worldSeed, NULL);
|
&worldSeed, NULL);
|
||||||
|
|
||||||
@ -1201,7 +1200,7 @@ int findStrongholds(const int mcversion, LayerStack *g, int *cache,
|
|||||||
x = (int)round(cos(angle) * distance);
|
x = (int)round(cos(angle) * distance);
|
||||||
z = (int)round(sin(angle) * distance);
|
z = (int)round(sin(angle) * distance);
|
||||||
|
|
||||||
locations[i] = findBiomePosition(mcversion, *g, cache,
|
locations[i] = findBiomePosition(mcversion, l, cache,
|
||||||
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
(x << 4) + 8, (z << 4) + 8, 112, validStrongholdBiomes,
|
||||||
&worldSeed, NULL);
|
&worldSeed, NULL);
|
||||||
|
|
||||||
@ -1269,38 +1268,38 @@ static double getGrassProbability(int64_t seed, int biome, int x, int z)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int canCoordinateBeSpawn(const int64_t seed, LayerStack *g, int *cache, Pos pos)
|
static int canCoordinateBeSpawn(const int64_t seed, const LayerStack *g, int *cache, Pos pos)
|
||||||
{
|
{
|
||||||
int biome = getBiomeAtPos(*g, pos);
|
int biome = getBiomeAtPos(*g, pos);
|
||||||
return getGrassProbability(seed, biome, pos.x, pos.z) >= 0.5;
|
return getGrassProbability(seed, biome, pos.x, pos.z) >= 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int* getValidSpawnBiomes()
|
|
||||||
|
static const char* getValidSpawnBiomes()
|
||||||
{
|
{
|
||||||
static int isSpawnBiome[256];
|
static const int biomesToSpawnIn[] = {forest, plains, taiga, taiga_hills, wooded_hills, jungle, jungle_hills};
|
||||||
|
static char isValid[256];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!isSpawnBiome[biomesToSpawnIn[0]])
|
if (!isValid[biomesToSpawnIn[0]])
|
||||||
{
|
|
||||||
for (i = 0; i < sizeof(biomesToSpawnIn) / sizeof(int); i++)
|
for (i = 0; i < sizeof(biomesToSpawnIn) / sizeof(int); i++)
|
||||||
{
|
isValid[ biomesToSpawnIn[i] ] = 1;
|
||||||
isSpawnBiome[ biomesToSpawnIn[i] ] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isSpawnBiome;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pos getSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed)
|
Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed)
|
||||||
{
|
{
|
||||||
const int *isSpawnBiome = getValidSpawnBiomes();
|
const char *isSpawnBiome = getValidSpawnBiomes();
|
||||||
Pos spawn;
|
Pos spawn;
|
||||||
int found;
|
int found;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
const Layer *l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
|
||||||
setSeed(&worldSeed);
|
setSeed(&worldSeed);
|
||||||
spawn = findBiomePosition(mcversion, *g, cache, 0, 0, 256, isSpawnBiome,
|
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
|
||||||
&worldSeed, &found);
|
&worldSeed, &found);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
@ -1361,14 +1360,16 @@ Pos getSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pos estimateSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed)
|
Pos estimateSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed)
|
||||||
{
|
{
|
||||||
const int *isSpawnBiome = getValidSpawnBiomes();
|
const char *isSpawnBiome = getValidSpawnBiomes();
|
||||||
Pos spawn;
|
Pos spawn;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
|
Layer *l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
|
||||||
setSeed(&worldSeed);
|
setSeed(&worldSeed);
|
||||||
spawn = findBiomePosition(mcversion, *g, cache, 0, 0, 256, isSpawnBiome,
|
spawn = findBiomePosition(mcversion, l, cache, 0, 0, 256, isSpawnBiome,
|
||||||
&worldSeed, &found);
|
&worldSeed, &found);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
@ -1386,15 +1387,9 @@ Pos estimateSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldS
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
|
||||||
int isViableFeaturePos(const int structureType, const LayerStack g, int *cache,
|
int isViableFeatureBiome(int structureType, int biomeID)
|
||||||
const int blockX, const int blockZ)
|
|
||||||
{
|
{
|
||||||
int *map = cache ? cache : allocCache(&g.layers[L_VORONOI_ZOOM_1], 1, 1);
|
switch (structureType)
|
||||||
genArea(&g.layers[L_VORONOI_ZOOM_1], map, blockX, blockZ, 1, 1);
|
|
||||||
int biomeID = map[0];
|
|
||||||
if (!cache) free(map);
|
|
||||||
|
|
||||||
switch(structureType)
|
|
||||||
{
|
{
|
||||||
case Desert_Pyramid:
|
case Desert_Pyramid:
|
||||||
return biomeID == desert || biomeID == desert_hills;
|
return biomeID == desert || biomeID == desert_hills;
|
||||||
@ -1410,73 +1405,193 @@ int isViableFeaturePos(const int structureType, const LayerStack g, int *cache,
|
|||||||
return isOceanic(biomeID) || biomeID == beach || biomeID == snowy_beach;
|
return isOceanic(biomeID) || biomeID == beach || biomeID == snowy_beach;
|
||||||
case Ruined_Portal:
|
case Ruined_Portal:
|
||||||
return 1;
|
return 1;
|
||||||
case Outpost:
|
case Treasure:
|
||||||
return biomeID == plains || biomeID == desert || biomeID == taiga || biomeID == snowy_tundra || biomeID == savanna;
|
return biomeID == beach || biomeID == snowy_beach || biomeID == stone_shore || biomeID == mushroom_field_shore;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Structure type is not valid for the scattered feature biome check.\n");
|
fprintf(stderr, "ERR isViableFeatureBiome: not implemented for structure type.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isViableVillagePos(const LayerStack g, int *cache,
|
static const char *getValidMonumentBiomes1()
|
||||||
const int blockX, const int blockZ)
|
|
||||||
{
|
{
|
||||||
static int isVillageBiome[0x100];
|
static const int oceanMonumentBiomeList1[] =
|
||||||
|
|
||||||
if (!isVillageBiome[villageBiomeList[0]])
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
ocean, deep_ocean, river, frozen_river,
|
||||||
for (i = 0; i < sizeof(villageBiomeList) / sizeof(int); i++)
|
frozen_ocean, deep_frozen_ocean, cold_ocean, deep_cold_ocean,
|
||||||
{
|
lukewarm_ocean, deep_lukewarm_ocean, warm_ocean, deep_warm_ocean
|
||||||
isVillageBiome[ villageBiomeList[i] ] = 1;
|
};
|
||||||
}
|
static char isValid[256];
|
||||||
}
|
unsigned int i;
|
||||||
|
|
||||||
return areBiomesViable(g, cache, blockX, blockZ, 0, isVillageBiome);
|
if (!isValid[oceanMonumentBiomeList1[0]])
|
||||||
}
|
|
||||||
|
|
||||||
int isViableOceanMonumentPos(const LayerStack g, int *cache,
|
|
||||||
const int blockX, const int blockZ)
|
|
||||||
{
|
|
||||||
static int isWaterBiome[0x100];
|
|
||||||
static int isDeepOcean[0x100];
|
|
||||||
|
|
||||||
if (!isWaterBiome[oceanMonumentBiomeList1[1]])
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < sizeof(oceanMonumentBiomeList1) / sizeof(int); i++)
|
for (i = 0; i < sizeof(oceanMonumentBiomeList1) / sizeof(int); i++)
|
||||||
{
|
isValid[ oceanMonumentBiomeList1[i] ] = 1;
|
||||||
isWaterBiome[ oceanMonumentBiomeList1[i] ] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(oceanMonumentBiomeList2) / sizeof(int); i++)
|
return isValid;
|
||||||
{
|
|
||||||
isDeepOcean[ oceanMonumentBiomeList2[i] ] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return areBiomesViable(g, cache, blockX, blockZ, 16, isDeepOcean) &&
|
|
||||||
areBiomesViable(g, cache, blockX, blockZ, 29, isWaterBiome);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int isViableMansionPos(const LayerStack g, int *cache,
|
static const char *getValidMonumentBiomes2()
|
||||||
const int blockX, const int blockZ)
|
|
||||||
{
|
{
|
||||||
static int isMansionBiome[0x100];
|
static const int oceanMonumentBiomeList2[] =
|
||||||
|
|
||||||
if (!isMansionBiome[mansionBiomeList[0]])
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
deep_frozen_ocean, deep_cold_ocean, deep_ocean,
|
||||||
for (i = 0; i < sizeof(mansionBiomeList) / sizeof(int); i++)
|
deep_lukewarm_ocean, deep_warm_ocean
|
||||||
{
|
};
|
||||||
isMansionBiome[ mansionBiomeList[i] ] = 1;
|
static char isValid[256];
|
||||||
}
|
unsigned int i;
|
||||||
}
|
|
||||||
|
|
||||||
return areBiomesViable(g, cache, blockX, blockZ, 32, isMansionBiome);
|
if (!isValid[oceanMonumentBiomeList2[0]])
|
||||||
|
for (i = 0; i < sizeof(oceanMonumentBiomeList2) / sizeof(int); i++)
|
||||||
|
isValid[ oceanMonumentBiomeList2[i] ] = 1;
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *getValidMansionBiomes()
|
||||||
|
{
|
||||||
|
static const int mansionBiomeList[] = {dark_forest, dark_forest+128};
|
||||||
|
static char isValid[256];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!isValid[mansionBiomeList[0]])
|
||||||
|
for (i = 0; i < sizeof(mansionBiomeList) / sizeof(int); i++)
|
||||||
|
isValid[ mansionBiomeList[i] ] = 1;
|
||||||
|
|
||||||
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int isViableStructurePos(const StructureConfig sconf, int mcversion,
|
||||||
|
LayerStack *g, int64_t seed, int blockX, int blockZ)
|
||||||
|
{
|
||||||
|
int biomeID;
|
||||||
|
int *map = NULL;
|
||||||
|
Layer *l;
|
||||||
|
|
||||||
|
int64_t chunkX = blockX >> 4;
|
||||||
|
int64_t chunkZ = blockZ >> 4;
|
||||||
|
|
||||||
|
// TODO: where possible perform cheaper biome checks before full validation
|
||||||
|
|
||||||
|
switch (sconf.structType)
|
||||||
|
{
|
||||||
|
case Desert_Pyramid:
|
||||||
|
case Igloo:
|
||||||
|
case Jungle_Pyramid:
|
||||||
|
case Swamp_Hut:
|
||||||
|
case Ocean_Ruin:
|
||||||
|
case Shipwreck:
|
||||||
|
case Ruined_Portal:
|
||||||
|
case Treasure:
|
||||||
|
if (mcversion < MC_1_16)
|
||||||
|
{
|
||||||
|
l = &g->layers[L_VORONOI_ZOOM_1];
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
map = allocCache(l, 1, 1);
|
||||||
|
genArea(l, map, blockX, blockZ, 1, 1);
|
||||||
|
}
|
||||||
|
else // position and layer check changed position in 1.16
|
||||||
|
{
|
||||||
|
l = &g->layers[L_RIVER_MIX_4]; // oceanic checks should be fine here
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
map = allocCache(l, 1, 1);
|
||||||
|
genArea(l, map, (chunkX << 2) + 2, (chunkZ << 2) + 2, 1, 1);
|
||||||
|
}
|
||||||
|
biomeID = map[0];
|
||||||
|
free(map);
|
||||||
|
return isViableFeatureBiome(sconf.structType, biomeID);
|
||||||
|
|
||||||
|
case Village:
|
||||||
|
l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
map = allocCache(l, 1, 1);
|
||||||
|
if (mcversion < MC_1_16) // TODO: check this (and if it makes a difference)
|
||||||
|
genArea(l, map, blockX >> 2, blockZ >> 2, 1, 1);
|
||||||
|
else
|
||||||
|
genArea(l, map, (chunkX << 2) + 2, (chunkZ << 2) + 2, 1, 1);
|
||||||
|
biomeID = map[0];
|
||||||
|
free(map);
|
||||||
|
if (biomeID == plains || biomeID == desert || biomeID == savanna || biomeID == taiga)
|
||||||
|
return 1;
|
||||||
|
if (mcversion >= MC_1_14 && biomeID == snowy_tundra)
|
||||||
|
return 1;
|
||||||
|
if (mcversion == MC_BE && biomeID == snowy_taiga)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case Outpost:
|
||||||
|
{
|
||||||
|
int64_t rnds = seed;
|
||||||
|
rnds ^= ((chunkX >> 4) ^ (chunkZ >> 4)) << 4;
|
||||||
|
setSeed(&rnds);
|
||||||
|
next(&rnds, 32);
|
||||||
|
if (nextInt(&rnds, 5) != 0)
|
||||||
|
return 0;
|
||||||
|
if (mcversion < MC_1_16)
|
||||||
|
{
|
||||||
|
l = &g->layers[L_VORONOI_ZOOM_1];
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
map = allocCache(l, 1, 1);
|
||||||
|
genArea(l, map, blockX, blockZ, 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l = &g->layers[L_RIVER_MIX_4]; // oceanic checks should be fine here
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
map = allocCache(l, 1, 1);
|
||||||
|
genArea(l, map, (chunkX << 2) + 2, (chunkZ << 2) + 2, 1, 1);
|
||||||
|
}
|
||||||
|
biomeID = map[0];
|
||||||
|
free(map);
|
||||||
|
// TODO: support for MC_BE
|
||||||
|
if (biomeID != plains && biomeID != desert && biomeID != taiga && biomeID != snowy_tundra && biomeID != savanna)
|
||||||
|
return 0;
|
||||||
|
// look for villages within 10 chunks
|
||||||
|
int cx0 = (chunkX-10), cx1 = (chunkX+10);
|
||||||
|
int cz0 = (chunkZ-10), cz1 = (chunkZ+10);
|
||||||
|
int rx, rz;
|
||||||
|
for (rz = cz0 >> 5; rz <= cz1 >> 5; rz++)
|
||||||
|
{
|
||||||
|
for (rx = cx0 >> 5; rx <= cx1 >> 5; rx++)
|
||||||
|
{
|
||||||
|
Pos p = getStructurePos(VILLAGE_CONFIG, seed, rx, rz);
|
||||||
|
int cx = p.x >> 4, cz = p.z >> 4;
|
||||||
|
if (cx >= cx0 && cx <= cx1 && cz >= cz0 && cz <= cz1)
|
||||||
|
{
|
||||||
|
if (mcversion >= MC_1_16)
|
||||||
|
return 0;
|
||||||
|
if (isViableStructurePos(VILLAGE_CONFIG, mcversion, g, seed, p.x, p.z))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Monument:
|
||||||
|
if (mcversion >= MC_1_13)
|
||||||
|
l = &g->layers[L13_OCEAN_MIX_4];
|
||||||
|
else
|
||||||
|
l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
if (areBiomesViable(l, NULL, blockX, blockZ, 16, getValidMonumentBiomes1()))
|
||||||
|
if (areBiomesViable(l, NULL, blockX, blockZ, 29, getValidMonumentBiomes2()))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case Mansion:
|
||||||
|
l = &g->layers[L_RIVER_MIX_4];
|
||||||
|
setWorldSeed(l, seed);
|
||||||
|
return areBiomesViable(l, NULL, blockX, blockZ, 32, getValidMansionBiomes());
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERR isViableStructurePos: validation for structure type not implemented");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -1496,7 +1611,7 @@ int isZombieVillage(const int mcversion, const int64_t worldSeed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the chunk position of the village
|
// get the chunk position of the village
|
||||||
seed = regionX*341873128712 + regionZ*132897987541 + seed + VILLAGE_CONFIG.seed;
|
seed = regionX*341873128712 + regionZ*132897987541 + seed + VILLAGE_CONFIG.salt;
|
||||||
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
seed = (seed ^ 0x5deece66dLL);// & ((1LL << 48) - 1);
|
||||||
|
|
||||||
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
seed = (seed * 0x5deece66dLL + 0xbLL) & 0xffffffffffff;
|
||||||
@ -1517,28 +1632,6 @@ int isZombieVillage(const int mcversion, const int64_t worldSeed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int isBabyZombieVillage(const int mcversion, const int64_t worldSeed,
|
|
||||||
const int regionX, const int regionZ)
|
|
||||||
{
|
|
||||||
if (!isZombieVillage(mcversion, worldSeed, regionX, regionZ))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Whether the zombie is a child or not is dependent on the world random
|
|
||||||
// object which is not reset for villages. The last reset is instead
|
|
||||||
// performed during the positioning of Mansions.
|
|
||||||
int64_t rnd = worldSeed;
|
|
||||||
rnd = regionX*341873128712 + regionZ*132897987541 + rnd + MANSION_CONFIG.seed;
|
|
||||||
setSeed(&rnd);
|
|
||||||
skipNextN(&rnd, 5);
|
|
||||||
|
|
||||||
int isChild = nextFloat(&rnd) < 0.05;
|
|
||||||
//int mountNearbyChicken = nextFloat(&rnd) < 0.05;
|
|
||||||
//int spawnNewChicken = nextFloat(&rnd) < 0.05;
|
|
||||||
|
|
||||||
return isChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ,
|
int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ,
|
||||||
int *out)
|
int *out)
|
||||||
{
|
{
|
||||||
@ -1563,233 +1656,6 @@ int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
|
||||||
int64_t filterAllTempCats(
|
|
||||||
LayerStack * g,
|
|
||||||
int * cache,
|
|
||||||
const int64_t * seedsIn,
|
|
||||||
int64_t * seedsOut,
|
|
||||||
const int64_t seedCnt,
|
|
||||||
const int centX,
|
|
||||||
const int centZ)
|
|
||||||
{
|
|
||||||
/* We require all temperature categories, including the special variations
|
|
||||||
* in order to get all main biomes. This gives 8 required values:
|
|
||||||
* Oceanic, Warm, Lush, Cold, Freezing,
|
|
||||||
* Special Warm, Special Lush, Special Cold
|
|
||||||
* These categories generate at Layer 13: Edge, Special.
|
|
||||||
*
|
|
||||||
* Note: The scale at this layer is 1:1024 and each element can "leak" its
|
|
||||||
* biome values up to 1024 blocks outwards into the negative coordinates
|
|
||||||
* (due to the Zoom layers).
|
|
||||||
*
|
|
||||||
* The plan is to check if the 3x3 area contains all 8 temperature types.
|
|
||||||
* For this, we can check even earlier at Layer 10: Add Island, that each of
|
|
||||||
* the Warm, Cold and Freezing categories are present.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Edit:
|
|
||||||
* All the biomes that are generated by a simple Cold climate can actually
|
|
||||||
* be generated later on. So I have commented out the Cold requirements.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const int pX = centX-1, pZ = centZ-1;
|
|
||||||
const int sX = 3, sZ = 3;
|
|
||||||
int *map;
|
|
||||||
|
|
||||||
Layer *lFilterSnow = &g->layers[L_ADD_SNOW_1024];
|
|
||||||
Layer *lFilterSpecial = &g->layers[L_SPECIAL_1024];
|
|
||||||
|
|
||||||
map = cache ? cache : allocCache(lFilterSpecial, sX, sZ);
|
|
||||||
|
|
||||||
int64_t sidx, hits, seed;
|
|
||||||
int types[9];
|
|
||||||
int specialCnt;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
hits = 0;
|
|
||||||
|
|
||||||
for (sidx = 0; sidx < seedCnt; sidx++)
|
|
||||||
{
|
|
||||||
seed = seedsIn[sidx];
|
|
||||||
|
|
||||||
/*** Pre-Generation Checks ***/
|
|
||||||
|
|
||||||
// We require at least 3 special temperature categories which can be
|
|
||||||
// tested for without going through the previous layers. (We'll get
|
|
||||||
// false positives due to Oceans, but this works fine to rule out some
|
|
||||||
// seeds early on.)
|
|
||||||
int64_t ss = getStartSeed(seed, lFilterSpecial->layerSeed);
|
|
||||||
specialCnt = 0;
|
|
||||||
for (i = 0; i < sX; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < sZ; j++)
|
|
||||||
{
|
|
||||||
int64_t cs = getChunkSeed(ss, i+pX, j+pZ);
|
|
||||||
if (mcFirstInt(cs, 13) == 0)
|
|
||||||
specialCnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (specialCnt < 3)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Cold/Warm Check ***/
|
|
||||||
|
|
||||||
// Continue by checking if enough cold and warm categories are present.
|
|
||||||
setWorldSeed(lFilterSnow, seed);
|
|
||||||
genArea(lFilterSnow, map, pX,pZ, sX,sZ);
|
|
||||||
|
|
||||||
memset(types, 0, sizeof(types));
|
|
||||||
for (i = 0; i < sX*sZ; i++)
|
|
||||||
types[map[i]]++;
|
|
||||||
|
|
||||||
// 1xOcean needs to be present
|
|
||||||
// 4xWarm need to turn into Warm, Lush, Special Warm and Special Lush
|
|
||||||
// 1xFreezing that needs to stay Freezing
|
|
||||||
// 3x(Cold + Freezing) for Cold, Special Cold and Freezing
|
|
||||||
if ( types[Ocean] < 1 || types[Warm] < 4 || types[Freezing] < 1 ||
|
|
||||||
types[Cold]+types[Freezing] < 2)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Complete Temperature Category Check ***/
|
|
||||||
|
|
||||||
// Check that all temperature variants are present.
|
|
||||||
setWorldSeed(lFilterSpecial, seed);
|
|
||||||
genArea(lFilterSpecial, map, pX,pZ, sX,sZ);
|
|
||||||
|
|
||||||
memset(types, 0, sizeof(types));
|
|
||||||
for (i = 0; i < sX*sZ; i++)
|
|
||||||
types[ map[i] > 4 ? (map[i]&0xf) + 4 : map[i] ]++;
|
|
||||||
|
|
||||||
if ( types[Ocean] < 1 || types[Warm] < 1 || types[Lush] < 1 ||
|
|
||||||
/*types[Cold] < 1 ||*/ types[Freezing] < 1 ||
|
|
||||||
types[Warm+4] < 1 || types[Lush+4] < 1 || types[Cold+4] < 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
for (i = 0; i < sX*sZ; i++)
|
|
||||||
{
|
|
||||||
printf("%c%d ", " s"[cache[i] > 4], cache[i]&0xf);
|
|
||||||
if (i % sX == sX-1) printf("\n");
|
|
||||||
}
|
|
||||||
printf("\n");*/
|
|
||||||
|
|
||||||
// Save the candidate.
|
|
||||||
seedsOut[hits] = seed;
|
|
||||||
hits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache == NULL) free(map);
|
|
||||||
return hits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const int majorBiomes[] = {
|
|
||||||
ocean, plains, desert, mountains, forest, taiga, swamp,
|
|
||||||
snowy_tundra, mushroom_fields, jungle, deep_ocean, birch_forest, dark_forest,
|
|
||||||
snowy_taiga, giant_tree_taiga, savanna, wooded_badlands_plateau, badlands_plateau
|
|
||||||
};
|
|
||||||
|
|
||||||
int64_t filterAllMajorBiomes(
|
|
||||||
LayerStack * g,
|
|
||||||
int * cache,
|
|
||||||
const int64_t * seedsIn,
|
|
||||||
int64_t * seedsOut,
|
|
||||||
const int64_t seedCnt,
|
|
||||||
const int pX,
|
|
||||||
const int pZ,
|
|
||||||
const unsigned int sX,
|
|
||||||
const unsigned int sZ)
|
|
||||||
{
|
|
||||||
Layer *lFilterMushroom = &g->layers[L_ADD_MUSHROOM_256];
|
|
||||||
Layer *lFilterBiomes = &g->layers[L_BIOME_256];
|
|
||||||
|
|
||||||
int *map;
|
|
||||||
int64_t sidx, seed, hits;
|
|
||||||
unsigned int i, id, hasAll;
|
|
||||||
|
|
||||||
int types[BIOME_NUM];
|
|
||||||
|
|
||||||
map = cache ? cache : allocCache(lFilterBiomes, sX, sZ);
|
|
||||||
|
|
||||||
hits = 0;
|
|
||||||
|
|
||||||
for (sidx = 0; sidx < seedCnt; sidx++)
|
|
||||||
{
|
|
||||||
/* We can use the Mushroom layer both to check for mushroom_fields biomes
|
|
||||||
* and to make sure all temperature categories are present in the area.
|
|
||||||
*/
|
|
||||||
seed = seedsIn[sidx];
|
|
||||||
setWorldSeed(lFilterMushroom, seed);
|
|
||||||
genArea(lFilterMushroom, map, pX,pZ, sX,sZ);
|
|
||||||
|
|
||||||
memset(types, 0, sizeof(types));
|
|
||||||
for (i = 0; i < sX*sZ; i++)
|
|
||||||
{
|
|
||||||
id = map[i];
|
|
||||||
if (id >= BIOME_NUM) id = (id & 0xf) + 4;
|
|
||||||
types[id]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( types[Ocean] < 1 || types[Warm] < 1 || types[Lush] < 1 ||
|
|
||||||
/* types[Cold] < 1 || */ types[Freezing] < 1 ||
|
|
||||||
types[Warm+4] < 1 || types[Lush+4] < 1 || types[Cold+4] < 1 ||
|
|
||||||
types[mushroom_fields] < 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Find all major biomes ***/
|
|
||||||
|
|
||||||
setWorldSeed(lFilterBiomes, seed);
|
|
||||||
genArea(lFilterBiomes, map, pX,pZ, sX,sZ);
|
|
||||||
|
|
||||||
memset(types, 0, sizeof(types));
|
|
||||||
for (i = 0; i < sX*sZ; i++)
|
|
||||||
{
|
|
||||||
types[map[i]]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasAll = 1;
|
|
||||||
for (i = 0; i < sizeof(majorBiomes) / sizeof(*majorBiomes); i++)
|
|
||||||
{
|
|
||||||
// plains, taiga and deep_ocean can be generated in later layers.
|
|
||||||
// Also small islands of Forests can be generated in deep_ocean
|
|
||||||
// biomes, but we are going to ignore those.
|
|
||||||
if (majorBiomes[i] == plains ||
|
|
||||||
majorBiomes[i] == taiga ||
|
|
||||||
majorBiomes[i] == deep_ocean)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (types[majorBiomes[i]] < 1)
|
|
||||||
{
|
|
||||||
hasAll = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasAll)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
seedsOut[hits] = seed;
|
|
||||||
hits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache == NULL) free(map);
|
|
||||||
return hits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BiomeFilter setupBiomeFilter(const int *biomeList, int listLen)
|
BiomeFilter setupBiomeFilter(const int *biomeList, int listLen)
|
||||||
{
|
{
|
||||||
BiomeFilter bf;
|
BiomeFilter bf;
|
||||||
@ -1978,7 +1844,7 @@ int64_t checkForBiomes(
|
|||||||
{
|
{
|
||||||
for (x = 0; x < areaWidth256; x++)
|
for (x = 0; x < areaWidth256; x++)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, (int64_t)(x + areaX256), (int64_t)(z + areaZ256));
|
cs = getChunkSeed(ss, x + areaX256, z + areaZ256);
|
||||||
if (mcFirstInt(cs, 100) == 0)
|
if (mcFirstInt(cs, 100) == 0)
|
||||||
{
|
{
|
||||||
goto after_protomushroom;
|
goto after_protomushroom;
|
||||||
@ -2004,7 +1870,7 @@ int64_t checkForBiomes(
|
|||||||
{
|
{
|
||||||
for (x = 0; x < areaWidth256; x++)
|
for (x = 0; x < areaWidth256; x++)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, (int64_t)(x + areaX256), (int64_t)(z + areaZ256));
|
cs = getChunkSeed(ss, x + areaX256, z + areaZ256);
|
||||||
cs >>= 24;
|
cs >>= 24;
|
||||||
|
|
||||||
int cs6 = cs % 6;
|
int cs6 = cs % 6;
|
||||||
|
175
finders.h
175
finders.h
@ -26,11 +26,14 @@ typedef pthread_t thread_id_t;
|
|||||||
#define LARGE_STRUCT 1
|
#define LARGE_STRUCT 1
|
||||||
#define CHUNK_STRUCT 2
|
#define CHUNK_STRUCT 2
|
||||||
|
|
||||||
enum
|
enum StructureType
|
||||||
{
|
{
|
||||||
|
// scattered features
|
||||||
Desert_Pyramid, Igloo, Jungle_Pyramid, Swamp_Hut,
|
Desert_Pyramid, Igloo, Jungle_Pyramid, Swamp_Hut,
|
||||||
|
//
|
||||||
Village, Ocean_Ruin, Shipwreck, Monument, Mansion, Outpost,
|
Village, Ocean_Ruin, Shipwreck, Monument, Mansion, Outpost,
|
||||||
Ruined_Portal
|
Ruined_Portal,
|
||||||
|
Treasure
|
||||||
};
|
};
|
||||||
|
|
||||||
enum // village house types prior to 1.14
|
enum // village house types prior to 1.14
|
||||||
@ -41,55 +44,41 @@ enum // village house types prior to 1.14
|
|||||||
|
|
||||||
STRUCT(StructureConfig)
|
STRUCT(StructureConfig)
|
||||||
{
|
{
|
||||||
int64_t seed;
|
int salt;
|
||||||
int regionSize, chunkRange;
|
char regionSize;
|
||||||
int properties;
|
char chunkRange;
|
||||||
|
unsigned char structType;
|
||||||
|
unsigned char properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for desert temples, igloos, jungle temples and witch huts prior to 1.13 */
|
/* for desert temples, igloos, jungle temples and witch huts prior to 1.13 */
|
||||||
static const StructureConfig FEATURE_CONFIG = { 14357617, 32, 24, 0};
|
static const StructureConfig FEATURE_CONFIG = { 14357617, 32, 24, Desert_Pyramid, 0};
|
||||||
|
|
||||||
/* ocean features before 1.16 */
|
/* ocean features before 1.16 */
|
||||||
static const StructureConfig OCEAN_RUIN_CONFIG_113 = { 14357621, 16, 8, 0};
|
static const StructureConfig OCEAN_RUIN_CONFIG_113 = { 14357621, 16, 8, Ocean_Ruin, 0};
|
||||||
static const StructureConfig SHIPWRECK_CONFIG_113 = {165745295, 15, 7, 0};
|
static const StructureConfig SHIPWRECK_CONFIG_113 = {165745295, 15, 7, Shipwreck, 0};
|
||||||
|
|
||||||
/* 1.13 separated feature seeds by type */
|
/* 1.13 separated feature seeds by type */
|
||||||
static const StructureConfig DESERT_PYRAMID_CONFIG = { 14357617, 32, 24, 0};
|
static const StructureConfig DESERT_PYRAMID_CONFIG = { 14357617, 32, 24, Desert_Pyramid, 0};
|
||||||
static const StructureConfig IGLOO_CONFIG = { 14357618, 32, 24, 0};
|
static const StructureConfig IGLOO_CONFIG = { 14357618, 32, 24, Igloo, 0};
|
||||||
static const StructureConfig JUNGLE_PYRAMID_CONFIG = { 14357619, 32, 24, 0};
|
static const StructureConfig JUNGLE_PYRAMID_CONFIG = { 14357619, 32, 24, Jungle_Pyramid, 0};
|
||||||
static const StructureConfig SWAMP_HUT_CONFIG = { 14357620, 32, 24, 0};
|
static const StructureConfig SWAMP_HUT_CONFIG = { 14357620, 32, 24, Swamp_Hut, 0};
|
||||||
|
|
||||||
static const StructureConfig OUTPOST_CONFIG = {165745296, 32, 24, 0};
|
static const StructureConfig OUTPOST_CONFIG = {165745296, 32, 24, Outpost, 0};
|
||||||
static const StructureConfig VILLAGE_CONFIG = { 10387312, 32, 24, 0};
|
static const StructureConfig VILLAGE_CONFIG = { 10387312, 32, 24, Village, 0};
|
||||||
static const StructureConfig OCEAN_RUIN_CONFIG = { 14357621, 20, 12, 0};
|
static const StructureConfig OCEAN_RUIN_CONFIG = { 14357621, 20, 12, Ocean_Ruin, 0};
|
||||||
static const StructureConfig SHIPWRECK_CONFIG = {165745295, 24, 20, 0};
|
static const StructureConfig SHIPWRECK_CONFIG = {165745295, 24, 20, Shipwreck, 0};
|
||||||
static const StructureConfig MONUMENT_CONFIG = { 10387313, 32, 27, LARGE_STRUCT};
|
static const StructureConfig MONUMENT_CONFIG = { 10387313, 32, 27, Monument, LARGE_STRUCT};
|
||||||
static const StructureConfig MANSION_CONFIG = { 10387319, 80, 60, LARGE_STRUCT};
|
static const StructureConfig MANSION_CONFIG = { 10387319, 80, 60, Mansion, LARGE_STRUCT};
|
||||||
static const StructureConfig RUINED_PORTAL_CONFIG = { 34222645, 40, 25, 0}; // overworld variant
|
static const StructureConfig RUINED_PORTAL_CONFIG = { 34222645, 40, 25, Ruined_Portal, 0}; // overworld variant
|
||||||
|
|
||||||
// structures that check each chunk individually
|
// structures that check each chunk individually
|
||||||
static const StructureConfig TREASURE_CONFIG = { 10387320, 1, 0, CHUNK_STRUCT};
|
static const StructureConfig TREASURE_CONFIG = { 10387320, 1, 0, Treasure, CHUNK_STRUCT};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Biome Tables
|
// Biome Tables
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
static const int templeBiomeList[] = {desert, desert_hills, jungle, jungle_hills, swamp, snowy_tundra, snowy_taiga};
|
|
||||||
static const int biomesToSpawnIn[] = {forest, plains, taiga, taiga_hills, wooded_hills, jungle, jungle_hills};
|
|
||||||
static const int villageBiomeList[] = {plains, desert, savanna, taiga};
|
|
||||||
static const int villageBiomeListBE[] = {plains, desert, savanna, taiga, snowy_tundra, snowy_taiga};
|
|
||||||
static const int mansionBiomeList[] = {dark_forest, dark_forest+128};
|
|
||||||
static const int oceanMonumentBiomeList1[] =
|
|
||||||
{
|
|
||||||
ocean, deep_ocean, river, frozen_river,
|
|
||||||
frozen_ocean, deep_frozen_ocean, cold_ocean, deep_cold_ocean,
|
|
||||||
lukewarm_ocean, deep_lukewarm_ocean, warm_ocean, deep_warm_ocean
|
|
||||||
};
|
|
||||||
static const int oceanMonumentBiomeList2[] =
|
|
||||||
{
|
|
||||||
deep_frozen_ocean, deep_cold_ocean, deep_ocean, deep_lukewarm_ocean, deep_warm_ocean
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int achievementBiomes_1_7[] =
|
static const int achievementBiomes_1_7[] =
|
||||||
{
|
{
|
||||||
ocean, plains, desert, extremeHills, forest, taiga, swampland, river, /*hell, sky,*/ // 0-9
|
ocean, plains, desert, extremeHills, forest, taiga, swampland, river, /*hell, sky,*/ // 0-9
|
||||||
@ -295,7 +284,7 @@ int getBiomeAtPos(const LayerStack g, const Pos pos);
|
|||||||
* Warning: accurate, but slow!
|
* Warning: accurate, but slow!
|
||||||
*
|
*
|
||||||
* @mcversion : Minecraft version (changed in: 1.7, 1.13)
|
* @mcversion : Minecraft version (changed in: 1.7, 1.13)
|
||||||
* @g : generator layer stack
|
* @l : entry layer with scale = 4
|
||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
* @cache : biome buffer, set to NULL for temporary allocation
|
||||||
* @centreX, centreZ : origin for the search
|
* @centreX, centreZ : origin for the search
|
||||||
* @range : square 'radius' of the search
|
* @range : square 'radius' of the search
|
||||||
@ -306,12 +295,12 @@ int getBiomeAtPos(const LayerStack g, const Pos pos);
|
|||||||
*/
|
*/
|
||||||
Pos findBiomePosition(
|
Pos findBiomePosition(
|
||||||
const int mcversion,
|
const int mcversion,
|
||||||
const LayerStack g,
|
const Layer * l,
|
||||||
int * cache,
|
int * cache,
|
||||||
const int centerX,
|
const int centerX,
|
||||||
const int centerZ,
|
const int centerZ,
|
||||||
const int range,
|
const int range,
|
||||||
const int * isValid,
|
const char * isValid,
|
||||||
int64_t * seed,
|
int64_t * seed,
|
||||||
int * passes
|
int * passes
|
||||||
);
|
);
|
||||||
@ -321,19 +310,19 @@ Pos findBiomePosition(
|
|||||||
* and mansions.
|
* and mansions.
|
||||||
* Warning: accurate, but slow!
|
* Warning: accurate, but slow!
|
||||||
*
|
*
|
||||||
* @g : generator layer stack
|
* @l : entry layer with scale = 4: (L_RIVER_MIX_4, L13_OCEAN_MIX_4)
|
||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
* @cache : biome buffer, set to NULL for temporary allocation
|
||||||
* @posX, posZ : centre for the check
|
* @posX, posZ : centre for the check
|
||||||
* @radius : 'radius' of the check area
|
* @radius : 'radius' of the check area
|
||||||
* @isValid : boolean array of valid biome ids (size = 256)
|
* @isValid : boolean array of valid biome ids (size = 256)
|
||||||
*/
|
*/
|
||||||
int areBiomesViable(
|
int areBiomesViable(
|
||||||
const LayerStack g,
|
const Layer * l,
|
||||||
int * cache,
|
int * cache,
|
||||||
const int posX,
|
const int posX,
|
||||||
const int posZ,
|
const int posZ,
|
||||||
const int radius,
|
const int radius,
|
||||||
const int * isValid
|
const char * isValid
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Finds the smallest radius (by square around the origin) at which all the
|
/* Finds the smallest radius (by square around the origin) at which all the
|
||||||
@ -380,7 +369,7 @@ int getBiomeRadius(
|
|||||||
*/
|
*/
|
||||||
int findStrongholds(
|
int findStrongholds(
|
||||||
const int mcversion,
|
const int mcversion,
|
||||||
LayerStack * g,
|
const LayerStack * g,
|
||||||
int * cache,
|
int * cache,
|
||||||
Pos * locations,
|
Pos * locations,
|
||||||
int64_t worldSeed,
|
int64_t worldSeed,
|
||||||
@ -397,7 +386,7 @@ int findStrongholds(
|
|||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
* @cache : biome buffer, set to NULL for temporary allocation
|
||||||
* @worldSeed : world seed used for the generator
|
* @worldSeed : world seed used for the generator
|
||||||
*/
|
*/
|
||||||
Pos getSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed);
|
Pos getSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed);
|
||||||
|
|
||||||
/* Finds the approximate spawn point in the world.
|
/* Finds the approximate spawn point in the world.
|
||||||
*
|
*
|
||||||
@ -406,54 +395,32 @@ Pos getSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed);
|
|||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
* @cache : biome buffer, set to NULL for temporary allocation
|
||||||
* @worldSeed : world seed used for the generator
|
* @worldSeed : world seed used for the generator
|
||||||
*/
|
*/
|
||||||
Pos estimateSpawn(const int mcversion, LayerStack *g, int *cache, int64_t worldSeed);
|
Pos estimateSpawn(const int mcversion, const LayerStack *g, int *cache, int64_t worldSeed);
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Validating Structure Positions
|
// Validating Structure Positions
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
/************************ Biome Checks for Structures **************************
|
|
||||||
*
|
|
||||||
* Scattered features only do a simple check of the biome at the block position
|
|
||||||
* of the structure origin (i.e. the north-west corner). Before 1.13 the type of
|
|
||||||
* structure was determined by the biome, while in 1.13 the scattered feature
|
|
||||||
* positions are calculated separately for each type. However, the biome
|
|
||||||
* requirements remain the same:
|
|
||||||
*
|
|
||||||
* Desert Pyramid: desert or desertHills
|
|
||||||
* Igloo : icePlains or coldTaiga
|
|
||||||
* Jungle Pyramid: jungle or jungleHills
|
|
||||||
* Swamp Hut : swampland
|
|
||||||
*
|
|
||||||
* Similarly, Ocean Ruins and Shipwrecks require any oceanic biome at their
|
|
||||||
* block position.
|
|
||||||
*
|
|
||||||
* Villages, Monuments and Mansions on the other hand require a certain area to
|
|
||||||
* be of a valid biome and the check is performed at a 1:4 scale instead of 1:1.
|
|
||||||
* (Actually the area for villages has a radius zero, which means it is a simple
|
|
||||||
* biome check at a 1:4 scale.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/* This function performs a biome check at the specified block coordinates to
|
||||||
/* These functions perform a biome check at the specified block coordinates to
|
|
||||||
* determine whether the corresponding structure would spawn there. You can get
|
* determine whether the corresponding structure would spawn there. You can get
|
||||||
* the block positions using the appropriate getXXXPos() function.
|
* the block positions using the appropriate getXXXPos() function.
|
||||||
*
|
*
|
||||||
* @g : generator layer stack [set seed using applySeed()]
|
* @sconf : structure config for the type to be checked
|
||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
* @mcversion : minecraft version
|
||||||
|
* @g : generator layer stack, seed will be applied to layers
|
||||||
|
* @seed : world seed, will be applied to generator
|
||||||
* @blockX, blockZ : block coordinates
|
* @blockX, blockZ : block coordinates
|
||||||
*
|
*
|
||||||
* In the case of isViableFeaturePos() the 'type' argument specifies the type of
|
|
||||||
* scattered feature (as an enum) for which the check is performed.
|
|
||||||
*
|
|
||||||
* The return value is non-zero if the position is valid.
|
* The return value is non-zero if the position is valid.
|
||||||
*/
|
*/
|
||||||
int isViableFeaturePos(const int type, const LayerStack g, int *cache, const int blockX, const int blockZ);
|
int isViableStructurePos(const StructureConfig sconf, int mcversion,
|
||||||
int isViableVillagePos(const LayerStack g, int *cache, const int blockX, const int blockZ);
|
LayerStack *g, int64_t seed, int blockX, int blockZ);
|
||||||
int isViableOceanMonumentPos(const LayerStack g, int *cache, const int blockX, const int blockZ);
|
|
||||||
int isViableMansionPos(const LayerStack g, int *cache, const int blockX, const int blockZ);
|
|
||||||
|
|
||||||
|
/* Checks if the specified structure type could generate in the given biome.
|
||||||
|
*/
|
||||||
|
int isViableFeatureBiome(int structureType, int biomeID);
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -479,12 +446,6 @@ inline static int64_t chunkGenerateRnd(const int64_t worldSeed, const int chunkX
|
|||||||
int isZombieVillage(const int mcversion, const int64_t worldSeed,
|
int isZombieVillage(const int mcversion, const int64_t worldSeed,
|
||||||
const int regionX, const int regionZ);
|
const int regionX, const int regionZ);
|
||||||
|
|
||||||
/* Checks if the village in the given region would generate as a baby zombie
|
|
||||||
* village. (The fact that these exist could be regarded as a bug.)
|
|
||||||
* (Minecraft 1.12)
|
|
||||||
*/
|
|
||||||
int isBabyZombieVillage(const int mcversion, const int64_t worldSeed,
|
|
||||||
const int regionX, const int regionZ);
|
|
||||||
|
|
||||||
/* Finds the number of each type of house that generate in a village.
|
/* Finds the number of each type of house that generate in a village.
|
||||||
* @worldSeed : world seed
|
* @worldSeed : world seed
|
||||||
@ -502,54 +463,6 @@ int64_t getHouseList(const int64_t worldSeed, const int chunkX, const int chunkZ
|
|||||||
// Seed Filters
|
// Seed Filters
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
/* Looks through the seeds in 'seedsIn' and copies those for which all
|
|
||||||
* temperature categories are present in the 3x3 area centred on the specified
|
|
||||||
* coordinates into 'seedsOut'. The map scale at this layer is 1:1024.
|
|
||||||
*
|
|
||||||
* @g : generator layer stack, (NOTE: seed will be modified)
|
|
||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
|
||||||
* @seedsIn : list of seeds to check
|
|
||||||
* @seedsOut : output buffer for the candidate seeds
|
|
||||||
* @seedCnt : number of seeds in 'seedsIn'
|
|
||||||
* @centX, centZ : search origin centre (in 1024 block units)
|
|
||||||
*
|
|
||||||
* Returns the number of found candidates.
|
|
||||||
*/
|
|
||||||
int64_t filterAllTempCats(
|
|
||||||
LayerStack * g,
|
|
||||||
int * cache,
|
|
||||||
const int64_t * seedsIn,
|
|
||||||
int64_t * seedsOut,
|
|
||||||
const int64_t seedCnt,
|
|
||||||
const int centX,
|
|
||||||
const int centZ
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Looks through the list of seeds in 'seedsIn' and copies those that have all
|
|
||||||
* major overworld biomes in the specified area into 'seedsOut'. These checks
|
|
||||||
* are done at a scale of 1:256.
|
|
||||||
*
|
|
||||||
* @g : generator layer stack, (NOTE: seed will be modified)
|
|
||||||
* @cache : biome buffer, set to NULL for temporary allocation
|
|
||||||
* @seedsIn : list of seeds to check
|
|
||||||
* @seedsOut : output buffer for the candidate seeds
|
|
||||||
* @seedCnt : number of seeds in 'seedsIn'
|
|
||||||
* @pX, pZ : search starting coordinates (in 256 block units)
|
|
||||||
* @sX, sZ : size of the searching area (in 256 block units)
|
|
||||||
*
|
|
||||||
* Returns the number of seeds found.
|
|
||||||
*/
|
|
||||||
int64_t filterAllMajorBiomes(
|
|
||||||
LayerStack * g,
|
|
||||||
int * cache,
|
|
||||||
const int64_t * seedsIn,
|
|
||||||
int64_t * seedsOut,
|
|
||||||
const int64_t seedCnt,
|
|
||||||
const int pX,
|
|
||||||
const int pZ,
|
|
||||||
const unsigned int sX,
|
|
||||||
const unsigned int sZ
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Creates a biome filter configuration from a given list of biomes.
|
/* Creates a biome filter configuration from a given list of biomes.
|
||||||
*/
|
*/
|
||||||
|
12
generator.c
12
generator.c
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
void setupLayer(Layer *l, Layer *p, int s,
|
void setupLayer(Layer *l, Layer *p, int s,
|
||||||
void (*getMap)(const Layer * RESTRICT, int *, int, int, int, int))
|
void (*getMap)(const Layer *, int *, int, int, int, int))
|
||||||
{
|
{
|
||||||
l->layerSeed = getLayerSeed(s);
|
l->layerSeed = getLayerSeed(s);
|
||||||
l->startSalt = 0;
|
l->startSalt = 0;
|
||||||
@ -21,7 +21,7 @@ void setupLayer(Layer *l, Layer *p, int s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s,
|
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s,
|
||||||
void (*getMap)(const Layer * RESTRICT, int *, int, int, int, int))
|
void (*getMap)(const Layer *, int *, int, int, int, int))
|
||||||
{
|
{
|
||||||
setupLayer(l, p1, s, getMap);
|
setupLayer(l, p1, s, getMap);
|
||||||
l->p2 = p2;
|
l->p2 = p2;
|
||||||
@ -79,7 +79,7 @@ static LayerStack setupGeneratorImpl(const int mcversion, const int largeBiomes)
|
|||||||
setupLayer(&l[L_DEEP_OCEAN_256], &l[L_ADD_MUSHROOM_256], 4, mapDeepOcean);
|
setupLayer(&l[L_DEEP_OCEAN_256], &l[L_ADD_MUSHROOM_256], 4, mapDeepOcean);
|
||||||
// biome layer chain
|
// biome layer chain
|
||||||
setupLayer(&l[L_BIOME_256], &l[L_DEEP_OCEAN_256], 200,
|
setupLayer(&l[L_BIOME_256], &l[L_DEEP_OCEAN_256], 200,
|
||||||
mcversion != MCBE ? mapBiome : mapBiomeBE);
|
mcversion != MC_BE ? mapBiome : mapBiomeBE);
|
||||||
|
|
||||||
if (mcversion <= MC_1_13)
|
if (mcversion <= MC_1_13)
|
||||||
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
||||||
@ -180,7 +180,7 @@ void freeGenerator(LayerStack g)
|
|||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
static void getMaxArea(Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
static void getMaxArea(const Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
||||||
{
|
{
|
||||||
if (layer == NULL)
|
if (layer == NULL)
|
||||||
return;
|
return;
|
||||||
@ -224,7 +224,7 @@ static void getMaxArea(Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
|||||||
getMaxArea(layer->p2, areaX, areaZ, maxX, maxZ);
|
getMaxArea(layer->p2, areaX, areaZ, maxX, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
int calcRequiredBuf(Layer *layer, int areaX, int areaZ)
|
int calcRequiredBuf(const Layer *layer, int areaX, int areaZ)
|
||||||
{
|
{
|
||||||
int maxX = areaX, maxZ = areaZ;
|
int maxX = areaX, maxZ = areaZ;
|
||||||
getMaxArea(layer, areaX, areaZ, &maxX, &maxZ);
|
getMaxArea(layer, areaX, areaZ, &maxX, &maxZ);
|
||||||
@ -232,7 +232,7 @@ int calcRequiredBuf(Layer *layer, int areaX, int areaZ)
|
|||||||
return maxX * maxZ;
|
return maxX * maxZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int *allocCache(Layer *layer, int sizeX, int sizeZ)
|
int *allocCache(const Layer *layer, int sizeX, int sizeZ)
|
||||||
{
|
{
|
||||||
int size = calcRequiredBuf(layer, sizeX, sizeZ);
|
int size = calcRequiredBuf(layer, sizeX, sizeZ);
|
||||||
|
|
||||||
|
13
generator.h
13
generator.h
@ -8,7 +8,7 @@ enum MCversion
|
|||||||
{
|
{
|
||||||
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
|
MC_1_7, MC_1_8, MC_1_9, MC_1_10, MC_1_11, MC_1_12, MC_1_13, MC_1_14,
|
||||||
MC_1_15, MC_1_16,
|
MC_1_15, MC_1_16,
|
||||||
MCBE = 256
|
MC_BE = 128
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Enumeration of the layer indices in the generator. */
|
/* Enumeration of the layer indices in the generator. */
|
||||||
@ -211,18 +211,17 @@ void freeGenerator(LayerStack g);
|
|||||||
/* 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
|
||||||
* dimensions 'sizeX' by 'sizeZ' at the specified layer.
|
* dimensions 'sizeX' by 'sizeZ' at the specified layer.
|
||||||
*/
|
*/
|
||||||
int calcRequiredBuf(Layer *layer, int areaX, int areaZ);
|
int calcRequiredBuf(const Layer *layer, int areaX, int areaZ);
|
||||||
|
|
||||||
/* Allocates an amount of memory required to generate an area of dimensions
|
/* Allocates an amount of memory required to generate an area of dimensions
|
||||||
* 'sizeX' by 'sizeZ' for the magnification of the current top layer.
|
* 'sizeX' by 'sizeZ' for the magnification of the current top layer.
|
||||||
*/
|
*/
|
||||||
int *allocCache(Layer *layer, int sizeX, int sizeZ);
|
int *allocCache(const Layer *layer, int sizeX, int sizeZ);
|
||||||
|
|
||||||
|
|
||||||
/* Set up custom layers. */
|
/* Set up custom layers. */
|
||||||
void setupLayer(Layer *l, Layer *p, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h));
|
void setupLayer(Layer *l, Layer *p, int s, void (*getMap)(const Layer *, int *, int, int, int, int));
|
||||||
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h));
|
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(const Layer *, int *, int, int, int, int));
|
||||||
|
|
||||||
|
|
||||||
/* Sets the world seed for the generator */
|
/* Sets the world seed for the generator */
|
||||||
void applySeed(LayerStack *g, int64_t seed);
|
void applySeed(LayerStack *g, int64_t seed);
|
||||||
@ -233,7 +232,7 @@ void applySeed(LayerStack *g, int64_t seed);
|
|||||||
* It is recommended that 'out' is allocated using allocCache() for the correct
|
* It is recommended that 'out' is allocated using allocCache() for the correct
|
||||||
* buffer size.
|
* buffer size.
|
||||||
*/
|
*/
|
||||||
void genArea(Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
void genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
205
layers.c
205
layers.c
@ -148,35 +148,32 @@ void initBiomes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setWorldSeed(Layer *layer, int64_t seed)
|
void setWorldSeed(Layer *layer, int64_t worldSeed)
|
||||||
{
|
{
|
||||||
if (layer->p2 != NULL && layer->getMap != mapHills)
|
if (layer->p2 != NULL && layer->getMap != mapHills)
|
||||||
setWorldSeed(layer->p2, seed);
|
setWorldSeed(layer->p2, worldSeed);
|
||||||
|
|
||||||
if (layer->p != NULL)
|
if (layer->p != NULL)
|
||||||
setWorldSeed(layer->p, seed);
|
setWorldSeed(layer->p, worldSeed);
|
||||||
|
|
||||||
if (layer->oceanRnd != NULL)
|
if (layer->oceanRnd != NULL)
|
||||||
oceanRndInit(layer->oceanRnd, seed);
|
oceanRndInit(layer->oceanRnd, worldSeed);
|
||||||
|
|
||||||
layer->startSalt = seed;
|
int64_t st = worldSeed;
|
||||||
layer->startSalt *= layer->startSalt * 6364136223846793005LL + 1442695040888963407LL;
|
st = mcStepSeed(st, layer->layerSeed);
|
||||||
layer->startSalt += layer->layerSeed;
|
st = mcStepSeed(st, layer->layerSeed);
|
||||||
layer->startSalt *= layer->startSalt * 6364136223846793005LL + 1442695040888963407LL;
|
st = mcStepSeed(st, layer->layerSeed);
|
||||||
layer->startSalt += layer->layerSeed;
|
|
||||||
layer->startSalt *= layer->startSalt * 6364136223846793005LL + 1442695040888963407LL;
|
|
||||||
layer->startSalt += layer->layerSeed;
|
|
||||||
|
|
||||||
layer->startSeed = layer->startSalt;
|
layer->startSalt = st;
|
||||||
layer->startSeed *= layer->startSeed * 6364136223846793005LL + 1442695040888963407LL;
|
layer->startSeed = mcStepSeed(st, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapNull(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapNull(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapSkip(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapSkip(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
if (l->p == NULL)
|
if (l->p == NULL)
|
||||||
{
|
{
|
||||||
@ -187,7 +184,7 @@ void mapSkip(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapIsland(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
register int i, j;
|
register int i, j;
|
||||||
|
|
||||||
@ -199,7 +196,7 @@ void mapIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w
|
|||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i + x, j + z);
|
cs = getChunkSeed(ss, i + x, j + z);
|
||||||
out[i + j*w] = mcFirstInt(cs, 10) == 0;
|
out[i + j*w] = mcFirstIsZero(cs, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +369,7 @@ static inline __m128i select4ModeOrRandom(__m128i* cs, int ws, __m128i a1, __m12
|
|||||||
|
|
||||||
#if defined USE_SIMD && __AVX2__
|
#if defined USE_SIMD && __AVX2__
|
||||||
|
|
||||||
void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
void mapZoom(Layer *l, int* out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
||||||
{
|
{
|
||||||
int pWidth = (areaWidth>>1)+2, pHeight = (areaHeight>>1)+1;
|
int pWidth = (areaWidth>>1)+2, pHeight = (areaHeight>>1)+1;
|
||||||
|
|
||||||
@ -435,7 +432,7 @@ void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth,
|
|||||||
|
|
||||||
#elif defined USE_SIMD && defined __SSE4_2__
|
#elif defined USE_SIMD && defined __SSE4_2__
|
||||||
|
|
||||||
void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
void mapZoom(Layer *l, int* out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
||||||
{
|
{
|
||||||
int pWidth = (areaWidth>>1)+2, pHeight = (areaHeight>>1)+1;
|
int pWidth = (areaWidth>>1)+2, pHeight = (areaHeight>>1)+1;
|
||||||
|
|
||||||
@ -497,7 +494,7 @@ void mapZoom(Layer *l, int* __restrict out, int areaX, int areaZ, int areaWidth,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x >> 1;
|
int pX = x >> 1;
|
||||||
int pZ = z >> 1;
|
int pZ = z >> 1;
|
||||||
@ -509,7 +506,7 @@ void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
|
|
||||||
int newW = (pW) << 1;
|
int newW = (pW) << 1;
|
||||||
int newH = (pH) << 1;
|
int newH = (pH) << 1;
|
||||||
int idx, a, b;
|
int idx, v00, v01;
|
||||||
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
|
int *buf = (int*) malloc((newW+1)*(newH+1)*sizeof(*buf));
|
||||||
|
|
||||||
const int st = (int)l->startSalt;
|
const int st = (int)l->startSalt;
|
||||||
@ -520,18 +517,18 @@ void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
for (j = 0; j < pH; j++)
|
for (j = 0; j < pH; j++)
|
||||||
{
|
{
|
||||||
idx = (j << 1) * newW;
|
idx = (j << 1) * newW;
|
||||||
a = out[(j+0)*pW];
|
v00 = out[(j+0)*pW];
|
||||||
b = out[(j+1)*pW];
|
v01 = out[(j+1)*pW];
|
||||||
|
|
||||||
for (i = 0; i < pW; i++)
|
for (i = 0; i < pW; i++)
|
||||||
{
|
{
|
||||||
int a1 = out[i+1 + (j+0)*pW];
|
int v10 = out[i+1 + (j+0)*pW];
|
||||||
int b1 = out[i+1 + (j+1)*pW];
|
int v11 = out[i+1 + (j+1)*pW];
|
||||||
|
|
||||||
const int chunkX = (i + pX) << 1;
|
int chunkX = (i + pX) << 1;
|
||||||
const int chunkZ = (j + pZ) << 1;
|
int chunkZ = (j + pZ) << 1;
|
||||||
|
|
||||||
register int cs = ss;
|
int cs = ss;
|
||||||
cs += chunkX;
|
cs += chunkX;
|
||||||
cs *= cs * 1284865837 + 4150755663;
|
cs *= cs * 1284865837 + 4150755663;
|
||||||
cs += chunkZ;
|
cs += chunkZ;
|
||||||
@ -540,13 +537,13 @@ void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
cs *= cs * 1284865837 + 4150755663;
|
cs *= cs * 1284865837 + 4150755663;
|
||||||
cs += chunkZ;
|
cs += chunkZ;
|
||||||
|
|
||||||
buf[idx] = a;
|
buf[idx] = v00;
|
||||||
buf[idx + newW] = (cs >> 24) & 1 ? b : a;
|
buf[idx + newW] = (cs >> 24) & 1 ? v01 : v00;
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
cs *= cs * 1284865837 + 4150755663;
|
cs *= cs * 1284865837 + 4150755663;
|
||||||
cs += st;
|
cs += st;
|
||||||
buf[idx] = (cs >> 24) & 1 ? a1 : a;
|
buf[idx] = (cs >> 24) & 1 ? v10 : v00;
|
||||||
|
|
||||||
|
|
||||||
if (isHighestZoom)
|
if (isHighestZoom)
|
||||||
@ -554,34 +551,36 @@ void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
//selectRandom4
|
//selectRandom4
|
||||||
cs *= cs * 1284865837 + 4150755663;
|
cs *= cs * 1284865837 + 4150755663;
|
||||||
cs += st;
|
cs += st;
|
||||||
const int i = (cs >> 24) & 3;
|
int r = (cs >> 24) & 3;
|
||||||
buf[idx + newW] = i==0 ? a : i==1 ? a1 : i==2 ? b : b1;
|
buf[idx + newW] = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//selectModeOrRandom
|
//selectModeOrRandom
|
||||||
if (a1 == b && b == b1) buf[idx + newW] = a1;
|
int v;
|
||||||
else if (a == a1 && a == b ) buf[idx + newW] = a;
|
if (v10 == v01 && v01 == v11) v = v10;
|
||||||
else if (a == a1 && a == b1) buf[idx + newW] = a;
|
else if (v00 == v10 && v00 == v01) v = v00;
|
||||||
else if (a == b && a == b1) buf[idx + newW] = a;
|
else if (v00 == v10 && v00 == v11) v = v00;
|
||||||
else if (a == a1 && b != b1) buf[idx + newW] = a;
|
else if (v00 == v01 && v00 == v11) v = v00;
|
||||||
else if (a == b && a1 != b1) buf[idx + newW] = a;
|
else if (v00 == v10 && v01 != v11) v = v00;
|
||||||
else if (a == b1 && a1 != b ) buf[idx + newW] = a;
|
else if (v00 == v01 && v10 != v11) v = v00;
|
||||||
else if (a1 == b && a != b1) buf[idx + newW] = a1;
|
else if (v00 == v11 && v10 != v01) v = v00;
|
||||||
else if (a1 == b1 && a != b ) buf[idx + newW] = a1;
|
else if (v10 == v01 && v00 != v11) v = v10;
|
||||||
else if (b == b1 && a != a1) buf[idx + newW] = b;
|
else if (v10 == v11 && v00 != v01) v = v10;
|
||||||
|
else if (v01 == v11 && v00 != v10) v = v01;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cs *= cs * 1284865837 + 4150755663;
|
cs *= cs * 1284865837 + 4150755663;
|
||||||
cs += st;
|
cs += st;
|
||||||
const int i = (cs >> 24) & 3;
|
int r = (cs >> 24) & 3;
|
||||||
buf[idx + newW] = i==0 ? a : i==1 ? a1 : i==2 ? b : b1;
|
v = r==0 ? v00 : r==1 ? v10 : r==2 ? v01 : v11;
|
||||||
}
|
}
|
||||||
|
buf[idx + newW] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx++;
|
idx++;
|
||||||
a = a1;
|
v00 = v10;
|
||||||
b = b1;
|
v01 = v11;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +594,7 @@ void mapZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void mapAddIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapAddIsland(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -683,7 +682,7 @@ void mapAddIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapRemoveTooMuchOcean(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapRemoveTooMuchOcean(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -711,7 +710,7 @@ void mapRemoveTooMuchOcean(const Layer * RESTRICT l, int * RESTRICT out, int x,
|
|||||||
if (v11 == 0)
|
if (v11 == 0)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i+x, j+z);
|
cs = getChunkSeed(ss, i+x, j+z);
|
||||||
if (mcFirstInt(cs, 2) == 0)
|
if (mcFirstIsZero(cs, 2))
|
||||||
{
|
{
|
||||||
out[i + j*w] = 1;
|
out[i + j*w] = 1;
|
||||||
}
|
}
|
||||||
@ -721,7 +720,7 @@ void mapRemoveTooMuchOcean(const Layer * RESTRICT l, int * RESTRICT out, int x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapAddSnow(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapAddSnow(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -761,7 +760,7 @@ void mapAddSnow(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapCoolWarm(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapCoolWarm(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -796,7 +795,7 @@ void mapCoolWarm(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapHeatIce(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapHeatIce(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -831,7 +830,7 @@ void mapHeatIce(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapSpecial(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapSpecial(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
l->p->getMap(l->p, out, x, z, w, h);
|
l->p->getMap(l->p, out, x, z, w, h);
|
||||||
|
|
||||||
@ -849,7 +848,7 @@ void mapSpecial(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
|
|
||||||
cs = getChunkSeed(ss, i+x, j+z);
|
cs = getChunkSeed(ss, i+x, j+z);
|
||||||
|
|
||||||
if (mcFirstInt(cs, 13) == 0)
|
if (mcFirstIsZero(cs, 13))
|
||||||
{
|
{
|
||||||
cs = mcStepSeed(cs, st);
|
cs = mcStepSeed(cs, st);
|
||||||
v |= (1 + mcFirstInt(cs, 15)) << 8 & 0xf00;
|
v |= (1 + mcFirstInt(cs, 15)) << 8 & 0xf00;
|
||||||
@ -861,7 +860,7 @@ void mapSpecial(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapAddMushroomIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapAddMushroomIsland(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -884,7 +883,7 @@ void mapAddMushroomIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, i
|
|||||||
if (v11 == 0 && !out[i+0 + (j+0)*pW] && !out[i+2 + (j+0)*pW] && !out[i+0 + (j+2)*pW] && !out[i+2 + (j+2)*pW])
|
if (v11 == 0 && !out[i+0 + (j+0)*pW] && !out[i+2 + (j+0)*pW] && !out[i+0 + (j+2)*pW] && !out[i+2 + (j+2)*pW])
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i+x, j+z);
|
cs = getChunkSeed(ss, i+x, j+z);
|
||||||
if (mcFirstInt(cs, 100) == 0)
|
if (mcFirstIsZero(cs, 100))
|
||||||
{
|
{
|
||||||
out[i + j*w] = mushroom_fields;
|
out[i + j*w] = mushroom_fields;
|
||||||
continue;
|
continue;
|
||||||
@ -897,7 +896,7 @@ void mapAddMushroomIsland(const Layer * RESTRICT l, int * RESTRICT out, int x, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapDeepOcean(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapDeepOcean(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -958,7 +957,7 @@ const int lushBiomes[] = {forest, dark_forest, mountains, plains, birch_forest,
|
|||||||
const int coldBiomes[] = {forest, mountains, taiga, plains};
|
const int coldBiomes[] = {forest, mountains, taiga, plains};
|
||||||
const int snowBiomes[] = {snowy_tundra, snowy_tundra, snowy_tundra, snowy_taiga};
|
const int snowBiomes[] = {snowy_tundra, snowy_tundra, snowy_tundra, snowy_taiga};
|
||||||
|
|
||||||
void mapBiome(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapBiome(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
l->p->getMap(l->p, out, x, z, w, h);
|
l->p->getMap(l->p, out, x, z, w, h);
|
||||||
|
|
||||||
@ -985,7 +984,7 @@ void mapBiome(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
|
|
||||||
switch(id){
|
switch(id){
|
||||||
case Warm:
|
case Warm:
|
||||||
if (hasHighBit) out[idx] = (mcFirstInt(cs, 3) == 0) ? badlands_plateau : wooded_badlands_plateau;
|
if (hasHighBit) out[idx] = mcFirstIsZero(cs, 3) ? badlands_plateau : wooded_badlands_plateau;
|
||||||
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
|
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
|
||||||
break;
|
break;
|
||||||
case Lush:
|
case Lush:
|
||||||
@ -1009,7 +1008,7 @@ void mapBiome(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
|
|
||||||
const int lushBiomesBE[] = {forest, dark_forest, mountains, plains, plains, plains, birch_forest, swamp};
|
const int lushBiomesBE[] = {forest, dark_forest, mountains, plains, plains, plains, birch_forest, swamp};
|
||||||
|
|
||||||
void mapBiomeBE(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapBiomeBE(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
l->p->getMap(l->p, out, x, z, w, h);
|
l->p->getMap(l->p, out, x, z, w, h);
|
||||||
|
|
||||||
@ -1036,7 +1035,7 @@ void mapBiomeBE(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
|
|
||||||
switch(id){
|
switch(id){
|
||||||
case Warm:
|
case Warm:
|
||||||
if (hasHighBit) out[idx] = (mcFirstInt(cs, 3) == 0) ? badlands_plateau : wooded_badlands_plateau;
|
if (hasHighBit) out[idx] = mcFirstIsZero(cs, 3) ? badlands_plateau : wooded_badlands_plateau;
|
||||||
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
|
else out[idx] = warmBiomes[mcFirstInt(cs, 6)];
|
||||||
break;
|
break;
|
||||||
case Lush:
|
case Lush:
|
||||||
@ -1058,7 +1057,7 @@ void mapBiomeBE(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapRiverInit(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapRiverInit(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
l->p->getMap(l->p, out, x, z, w, h);
|
l->p->getMap(l->p, out, x, z, w, h);
|
||||||
|
|
||||||
@ -1084,7 +1083,7 @@ void mapRiverInit(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapAddBamboo(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapAddBamboo(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
l->p->getMap(l->p, out, x, z, w, h);
|
l->p->getMap(l->p, out, x, z, w, h);
|
||||||
|
|
||||||
@ -1100,7 +1099,7 @@ void mapAddBamboo(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
if (out[idx] != jungle) continue;
|
if (out[idx] != jungle) continue;
|
||||||
|
|
||||||
cs = getChunkSeed(ss, i + x, j + z);
|
cs = getChunkSeed(ss, i + x, j + z);
|
||||||
if (mcFirstInt(cs, 10) == 0)
|
if (mcFirstIsZero(cs, 10))
|
||||||
{
|
{
|
||||||
out[idx] = bamboo_jungle;
|
out[idx] = bamboo_jungle;
|
||||||
}
|
}
|
||||||
@ -1123,7 +1122,7 @@ static inline int replaceEdge(int *out, int idx, int v10, int v21, int v01, int
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapBiomeEdge(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapBiomeEdge(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1190,7 +1189,7 @@ void mapBiomeEdge(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapHills(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapHills(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1233,7 +1232,7 @@ void mapHills(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i + x, j + z);
|
cs = getChunkSeed(ss, i + x, j + z);
|
||||||
if (mcFirstInt(cs, 3) != 0 && !var12)
|
if (mcFirstIsZero(cs, 3) && !var12)
|
||||||
{
|
{
|
||||||
out[idx] = a11;
|
out[idx] = a11;
|
||||||
}
|
}
|
||||||
@ -1259,7 +1258,7 @@ void mapHills(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
hillID = snowy_taiga_hills; break;
|
hillID = snowy_taiga_hills; break;
|
||||||
case plains:
|
case plains:
|
||||||
cs = mcStepSeed(cs, st);
|
cs = mcStepSeed(cs, st);
|
||||||
hillID = (mcFirstInt(cs, 3) == 0) ? wooded_hills : forest; break;
|
hillID = mcFirstIsZero(cs, 3) ? wooded_hills : forest; break;
|
||||||
case snowy_tundra:
|
case snowy_tundra:
|
||||||
hillID = snowy_mountains; break;
|
hillID = snowy_mountains; break;
|
||||||
case jungle:
|
case jungle:
|
||||||
@ -1273,8 +1272,8 @@ void mapHills(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
default:
|
default:
|
||||||
if (areSimilar(a11, wooded_badlands_plateau))
|
if (areSimilar(a11, wooded_badlands_plateau))
|
||||||
hillID = badlands;
|
hillID = badlands;
|
||||||
else if (a11 == deep_ocean && mcFirstInt(cs = mcStepSeed(cs, st), 3) == 0)
|
else if (a11 == deep_ocean && mcFirstIsZero(cs = mcStepSeed(cs, st), 3))
|
||||||
hillID = (mcFirstInt(mcStepSeed(cs, st), 2) == 0) ? plains : forest;
|
hillID = mcFirstIsZero(mcStepSeed(cs, st), 2) ? plains : forest;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,7 +1316,7 @@ void mapHills(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapHills113(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapHills113(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1364,7 +1363,7 @@ void mapHills113(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i + x, j + z);
|
cs = getChunkSeed(ss, i + x, j + z);
|
||||||
if (mcFirstInt(cs, 3) == 0 || bn == 0)
|
if (bn == 0 || mcFirstIsZero(cs, 3))
|
||||||
{
|
{
|
||||||
int hillID = a11;
|
int hillID = a11;
|
||||||
|
|
||||||
@ -1386,7 +1385,7 @@ void mapHills113(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
hillID = snowy_taiga_hills; break;
|
hillID = snowy_taiga_hills; break;
|
||||||
case plains:
|
case plains:
|
||||||
cs = mcStepSeed(cs, st);
|
cs = mcStepSeed(cs, st);
|
||||||
hillID = (mcFirstInt(cs, 3) == 0) ? wooded_hills : forest; break;
|
hillID = mcFirstIsZero(cs, 3) ? wooded_hills : forest; break;
|
||||||
case snowy_tundra:
|
case snowy_tundra:
|
||||||
hillID = snowy_mountains; break;
|
hillID = snowy_mountains; break;
|
||||||
case jungle:
|
case jungle:
|
||||||
@ -1405,10 +1404,10 @@ void mapHills113(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
else if (isDeepOcean(a11))
|
else if (isDeepOcean(a11))
|
||||||
{
|
{
|
||||||
cs = mcStepSeed(cs, st);
|
cs = mcStepSeed(cs, st);
|
||||||
if (mcFirstInt(cs, 3) == 0)
|
if (mcFirstIsZero(cs, 3))
|
||||||
{
|
{
|
||||||
cs = mcStepSeed(cs, st);
|
cs = mcStepSeed(cs, st);
|
||||||
hillID = (mcFirstInt(cs, 2) == 0) ? plains : forest;
|
hillID = mcFirstIsZero(cs, 2) ? plains : forest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1462,7 +1461,7 @@ static inline int reduceID(int id)
|
|||||||
return id >= 2 ? 2 + (id & 1) : id;
|
return id >= 2 ? 2 + (id & 1) : id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapRiver(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapRiver(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1481,12 +1480,9 @@ void mapRiver(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
{
|
{
|
||||||
int v11 = reduceID(vz1[i+1]);
|
int v11 = reduceID(vz1[i+1]);
|
||||||
int v10 = reduceID(vz0[i+1]);
|
|
||||||
int v21 = reduceID(vz1[i+2]);
|
|
||||||
int v01 = reduceID(vz1[i+0]);
|
|
||||||
int v12 = reduceID(vz2[i+1]);
|
|
||||||
|
|
||||||
if (v11 == v01 && v11 == v10 && v11 == v21 && v11 == v12)
|
if (v11 == reduceID(vz1[i+0]) && v11 == reduceID(vz1[i+2]) &&
|
||||||
|
v11 == reduceID(vz0[i+1]) && v11 == reduceID(vz2[i+1]))
|
||||||
{
|
{
|
||||||
out[i + j * w] = -1;
|
out[i + j * w] = -1;
|
||||||
}
|
}
|
||||||
@ -1499,7 +1495,7 @@ void mapRiver(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapSmooth(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapSmooth(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1521,23 +1517,26 @@ void mapSmooth(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w
|
|||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
{
|
{
|
||||||
int v11 = vz1[i+1];
|
int v11 = vz1[i+1];
|
||||||
int v10 = vz0[i+1];
|
|
||||||
int v21 = vz1[i+2];
|
|
||||||
int v01 = vz1[i+0];
|
int v01 = vz1[i+0];
|
||||||
int v12 = vz2[i+1];
|
int v10 = vz0[i+1];
|
||||||
|
|
||||||
if (v01 == v21 && v10 == v12)
|
if (v11 != v01 || v11 != v10)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i+x, j+z);
|
int v21 = vz1[i+2];
|
||||||
if (cs & ((int64_t)1 << 24))
|
int v12 = vz2[i+1];
|
||||||
v11 = v10;
|
if (v01 == v21 && v10 == v12)
|
||||||
|
{
|
||||||
|
cs = getChunkSeed(ss, i+x, j+z);
|
||||||
|
if (cs & ((int64_t)1 << 24))
|
||||||
|
v11 = v10;
|
||||||
|
else
|
||||||
|
v11 = v01;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
v11 = v01;
|
{
|
||||||
}
|
if (v01 == v21) v11 = v01;
|
||||||
else
|
if (v10 == v12) v11 = v10;
|
||||||
{
|
}
|
||||||
if (v01 == v21) v11 = v01;
|
|
||||||
if (v10 == v12) v11 = v10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i + j * w] = v11;
|
out[i + j * w] = v11;
|
||||||
@ -1546,7 +1545,7 @@ void mapSmooth(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapRareBiome(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapRareBiome(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -1564,7 +1563,7 @@ void mapRareBiome(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
if (v == plains)
|
if (v == plains)
|
||||||
{
|
{
|
||||||
cs = getChunkSeed(ss, i + x, j + z);
|
cs = getChunkSeed(ss, i + x, j + z);
|
||||||
if (mcFirstInt(cs, 57) == 0)
|
if (mcFirstIsZero(cs, 57))
|
||||||
{
|
{
|
||||||
// Sunflower Plains
|
// Sunflower Plains
|
||||||
out[i + j*w] = plains + 128;
|
out[i + j*w] = plains + 128;
|
||||||
@ -1592,7 +1591,7 @@ inline static int isBiomeJFTO(int id)
|
|||||||
return biomeExists(id) && (getBiomeType(id) == Jungle || id == forest || id == taiga || isOceanic(id));
|
return biomeExists(id) && (getBiomeType(id) == Jungle || id == forest || id == taiga || isOceanic(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapShore(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapShore(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int pX = x - 1;
|
int pX = x - 1;
|
||||||
int pZ = z - 1;
|
int pZ = z - 1;
|
||||||
@ -1683,7 +1682,7 @@ void mapShore(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapRiverMix(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
int len;
|
int len;
|
||||||
@ -1821,7 +1820,7 @@ static double getOceanTemp(const OceanRnd *rnd, double d1, double d2, double d3)
|
|||||||
return lerp(t3, l1, l5);
|
return lerp(t3, l1, l5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapOceanTemp(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
OceanRnd *rnd = l->oceanRnd;
|
OceanRnd *rnd = l->oceanRnd;
|
||||||
@ -1847,7 +1846,7 @@ void mapOceanTemp(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Warning: this function is horribly slow compared to other layers! */
|
/* Warning: this function is horribly slow compared to other layers! */
|
||||||
void mapOceanMix(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int landX = x - 8, landZ = z - 8;
|
int landX = x - 8, landZ = z - 8;
|
||||||
int landW = w + 17, landH = h + 17;
|
int landW = w + 17, landH = h + 17;
|
||||||
@ -1936,7 +1935,7 @@ void mapOceanMix(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mapVoronoiZoom(const Layer * RESTRICT l, int * RESTRICT out, int x, int z, int w, int h)
|
void mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
x -= 2;
|
x -= 2;
|
||||||
z -= 2;
|
z -= 2;
|
||||||
|
68
layers.h
68
layers.h
@ -13,8 +13,6 @@
|
|||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RESTRICT __restrict
|
|
||||||
#define REGISTER register
|
|
||||||
|
|
||||||
#define STRUCT(S) typedef struct S S; struct S
|
#define STRUCT(S) typedef struct S S; struct S
|
||||||
|
|
||||||
@ -147,14 +145,14 @@ STRUCT(OceanRnd)
|
|||||||
STRUCT(Layer)
|
STRUCT(Layer)
|
||||||
{
|
{
|
||||||
int64_t layerSeed; // (depends only on layer salt)
|
int64_t layerSeed; // (depends only on layer salt)
|
||||||
int64_t startSalt; // (world seed dependent) for RND ints beyond the first
|
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
||||||
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
||||||
|
|
||||||
OceanRnd *oceanRnd; // world seed dependent data for ocean temperatures
|
OceanRnd *oceanRnd; // world seed dependent data for ocean temperatures
|
||||||
|
|
||||||
int scale; // map scale of this layer (map entry = scale x scale blocks)
|
int scale; // map scale of this layer (map entry = scale x scale blocks)
|
||||||
|
|
||||||
void (*getMap)(const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void (*getMap)(const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
Layer *p, *p2; // parent layers
|
Layer *p, *p2; // parent layers
|
||||||
};
|
};
|
||||||
@ -175,7 +173,7 @@ extern Biome biomes[256];
|
|||||||
void initBiomes();
|
void initBiomes();
|
||||||
|
|
||||||
/* Applies the given world seed to the layer and all dependent layers. */
|
/* Applies the given world seed to the layer and all dependent layers. */
|
||||||
void setWorldSeed(Layer *layer, int64_t seed);
|
void setWorldSeed(Layer *layer, int64_t worldSeed);
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -270,8 +268,8 @@ static inline int isBiomeSnowy(int id)
|
|||||||
* The seed pipeline:
|
* The seed pipeline:
|
||||||
*
|
*
|
||||||
* Salt of Layer -> layerSeed (ls)
|
* Salt of Layer -> layerSeed (ls)
|
||||||
* layerSeed (ls) + worldSeed (ws) -> startSalt (st) + startSeed (ss)
|
* layerSeed (ls) & worldSeed (ws) -> startSalt (st) & startSeed (ss)
|
||||||
* startSeed (ls) + coords (x,z) -> chunkSeed (cs)
|
* startSeed (ls) & coords (x,z) -> chunkSeed (cs)
|
||||||
*
|
*
|
||||||
* The chunkSeed alone is enough to generate the first RND integer with:
|
* The chunkSeed alone is enough to generate the first RND integer with:
|
||||||
* mcFirstInt(cs, mod)
|
* mcFirstInt(cs, mod)
|
||||||
@ -293,7 +291,7 @@ static inline int mcFirstInt(int64_t s, int mod)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int mcIsFirstZero(int64_t s, int mod)
|
static inline int mcFirstIsZero(int64_t s, int mod)
|
||||||
{
|
{
|
||||||
return (int)((s >> 24) % mod) == 0;
|
return (int)((s >> 24) % mod) == 0;
|
||||||
}
|
}
|
||||||
@ -332,40 +330,40 @@ static inline int64_t getStartSeed(int64_t ws, int64_t ls)
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
// A null layer does nothing, and can be used to apply a layer to existing data.
|
// A null layer does nothing, and can be used to apply a layer to existing data.
|
||||||
void mapNull (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapNull (const Layer *, int *, int, int, int, int);
|
||||||
// A skip layer simply calls its first parent without modification.
|
// A skip layer simply calls its first parent without modification.
|
||||||
// This can be used as an easy way to skip a layer in a generator.
|
// This can be used as an easy way to skip a layer in a generator.
|
||||||
void mapSkip (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapSkip (const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
void mapIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapIsland (const Layer *, int *, int, int, int, int);
|
||||||
void mapZoom (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapZoom (const Layer *, int *, int, int, int, int);
|
||||||
void mapAddIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapAddIsland (const Layer *, int *, int, int, int, int);
|
||||||
void mapRemoveTooMuchOcean (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapRemoveTooMuchOcean (const Layer *, int *, int, int, int, int);
|
||||||
void mapAddSnow (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapAddSnow (const Layer *, int *, int, int, int, int);
|
||||||
void mapCoolWarm (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapCoolWarm (const Layer *, int *, int, int, int, int);
|
||||||
void mapHeatIce (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapHeatIce (const Layer *, int *, int, int, int, int);
|
||||||
void mapSpecial (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapSpecial (const Layer *, int *, int, int, int, int);
|
||||||
void mapAddMushroomIsland (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapAddMushroomIsland (const Layer *, int *, int, int, int, int);
|
||||||
void mapDeepOcean (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapDeepOcean (const Layer *, int *, int, int, int, int);
|
||||||
void mapBiome (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapBiome (const Layer *, int *, int, int, int, int);
|
||||||
void mapBiomeBE (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapBiomeBE (const Layer *, int *, int, int, int, int);
|
||||||
void mapAddBamboo (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapAddBamboo (const Layer *, int *, int, int, int, int);
|
||||||
void mapRiverInit (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapRiverInit (const Layer *, int *, int, int, int, int);
|
||||||
void mapBiomeEdge (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapBiomeEdge (const Layer *, int *, int, int, int, int);
|
||||||
void mapHills (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapHills (const Layer *, int *, int, int, int, int);
|
||||||
void mapRiver (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapRiver (const Layer *, int *, int, int, int, int);
|
||||||
void mapSmooth (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapSmooth (const Layer *, int *, int, int, int, int);
|
||||||
void mapRareBiome (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapRareBiome (const Layer *, int *, int, int, int, int);
|
||||||
void mapShore (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapShore (const Layer *, int *, int, int, int, int);
|
||||||
void mapRiverMix (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapRiverMix (const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
// 1.13 layers
|
// 1.13 layers
|
||||||
void mapHills113 (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapHills113 (const Layer *, int *, int, int, int, int);
|
||||||
void mapOceanTemp (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapOceanTemp (const Layer *, int *, int, int, int, int);
|
||||||
void mapOceanMix (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapOceanMix (const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
// final layer 1:1
|
// final layer 1:1
|
||||||
void mapVoronoiZoom (const Layer * RESTRICT, int * RESTRICT, int, int, int, int);
|
void mapVoronoiZoom (const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
4
makefile
4
makefile
@ -16,7 +16,7 @@ endif
|
|||||||
.PHONY : all debug libcubiomes clean
|
.PHONY : all debug libcubiomes clean
|
||||||
|
|
||||||
all: CFLAGS += -O3 -march=native
|
all: CFLAGS += -O3 -march=native
|
||||||
all: find_quadhuts find_compactbiomes clean
|
all: libcubiomes find_quadhuts find_compactbiomes clean
|
||||||
|
|
||||||
debug: CFLAGS += -DDEBUG -O0 -ggdb3
|
debug: CFLAGS += -DDEBUG -O0 -ggdb3
|
||||||
debug: find_quadhuts find_compactbiomes clean
|
debug: find_quadhuts find_compactbiomes clean
|
||||||
@ -54,5 +54,5 @@ util.o: util.c util.h
|
|||||||
$(CC) -c $(CFLAGS) $<
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o
|
$(RM) *.o libcubiomes.a find_quadhuts find_compactbiomes
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user