Reworked structures for 1.13

This commit is contained in:
Cubitect 2018-07-04 16:18:21 +01:00
parent 1c313238d0
commit a2904fbcd5
9 changed files with 108137 additions and 147 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
find_compactbiomes find_compactbiomes
find_quadhuts find_quadhuts
.cproject
.project

View File

@ -23,23 +23,47 @@ int main(int argc, char *argv[])
int regPosX = 0; int regPosX = 0;
int regPosZ = 0; int regPosZ = 0;
int mcversion = 0;
const char *seedFileName;
long featureSeed;
if(argc > 2) if(argc > 2)
{ {
if(sscanf(argv[1], "%d", &regPosX) != 1) regPosX = 0; if(sscanf(argv[1], "%d", &regPosX) != 1) regPosX = 0;
if(sscanf(argv[2], "%d", &regPosZ) != 1) regPosZ = 0; if(sscanf(argv[2], "%d", &regPosZ) != 1) regPosZ = 0;
if(argc > 3)
{
if(sscanf(argv[3], "%d", &mcversion) != 1) mcversion = 0;
}
else
{
printf("MC version not specified. Set using 'mcversion' argument:\n"
"17 for MC1.7 - MC1.12\n113 for MC1.13+\n"
"Defaulting to MC 1.7.\n\n");
mcversion = 17;
}
} }
else else
{ {
printf("Usage:\n" printf("Usage:\n"
"find_quadhuts [regionX] [regionZ]\n" "find_quadhuts [regionX] [regionZ] [mcversion]\n"
"Defaulting to origin.\n\n"); "Defaulting to origin.\n\n");
} }
regPosX -= 1; regPosX -= 1;
regPosZ -= 1; regPosZ -= 1;
if(mcversion == 113)
const char *seedFileName = "./seeds/quadbases_Q1.txt"; {
featureSeed = SWAMP_HUT_SEED;
seedFileName = "./seeds/quadhutbases_1_13_Q1.txt";
}
else
{
featureSeed = FEATURE_SEED;
seedFileName = "./seeds/quadhutbases_1_7_Q1.txt";
}
if(access(seedFileName, F_OK)) if(access(seedFileName, F_OK))
{ {
@ -47,7 +71,7 @@ int main(int argc, char *argv[])
"This may take a few minutes...\n"); "This may take a few minutes...\n");
int threads = 6; int threads = 6;
int quality = 1; int quality = 1;
baseQuadWitchHutSearch(seedFileName, threads, quality); search4QuadBases(seedFileName, threads, featureSeed, quality);
} }
long i, j, qhcnt; long i, j, qhcnt;
@ -77,12 +101,12 @@ int main(int argc, char *argv[])
// Search for a swamp at the structure positions // Search for a swamp at the structure positions
for(i = 0; i < qhcnt; i++) for(i = 0; i < qhcnt; i++)
{ {
base = moveTemple(qhcandidates[i], regPosX, regPosZ); base = moveStructure(qhcandidates[i], regPosX, regPosZ);
qhpos[0] = getWitchHutPos(base, 0+regPosX, 0+regPosZ); qhpos[0] = getStructurePos(featureSeed, base, 0+regPosX, 0+regPosZ);
qhpos[1] = getWitchHutPos(base, 0+regPosX, 1+regPosZ); qhpos[1] = getStructurePos(featureSeed, base, 0+regPosX, 1+regPosZ);
qhpos[2] = getWitchHutPos(base, 1+regPosX, 0+regPosZ); qhpos[2] = getStructurePos(featureSeed, base, 1+regPosX, 0+regPosZ);
qhpos[3] = getWitchHutPos(base, 1+regPosX, 1+regPosZ); qhpos[3] = getStructurePos(featureSeed, base, 1+regPosX, 1+regPosZ);
/* /*
for(j = 0; j < 4; j++) for(j = 0; j < 4; j++)

195
finders.c
View File

@ -33,17 +33,14 @@ Biome biomes[256];
* *
* Minecraft uses a 48-bit pseudo random number generator (PRNG) to determine * Minecraft uses a 48-bit pseudo random number generator (PRNG) to determine
* the position of it's structures. The remaining top 16 bits do not influence * the position of it's structures. The remaining top 16 bits do not influence
* the structure positioning. Additionally the position of all temples in a * the structure positioning. Additionally the position of most structures in a
* world can be translated by applying the following transformation to the * world can be translated by applying the following transformation to the
* seed: * seed:
* *
* seed2 = seed1 - structureSeed - dregX * 341873128712 - dregZ * 132897987541; * seed2 = seed1 - dregX * 341873128712 - dregZ * 132897987541;
* *
* Here seed1 and seed2 have the same structure positioning, but moved by a * Here seed1 and seed2 have the same structure positioning, but moved by a
* region offset of (dregX,dregZ). [a region is 32x32 chunks]. The value of * region offset of (dregX,dregZ). [a region is 32x32 chunks].
* structureSeed depends on the type of structure, 14357617 for desert temples,
* 14357618 for igloos, 14357619 for jungle temples and 14357620 for witch
* huts.
* *
* For a quad-structure, we mainly care about relative positioning, so we can * For a quad-structure, we mainly care about relative positioning, so we can
* get away with just checking the regions near the origin: (0,0),(0,1),(1,0) * get away with just checking the regions near the origin: (0,0),(0,1),(1,0)
@ -70,6 +67,7 @@ Biome biomes[256];
typedef struct quad_threadinfo_t typedef struct quad_threadinfo_t
{ {
long start, end; long start, end;
long structureSeed;
int threadID; int threadID;
int quality; int quality;
const char *fnam; const char *fnam;
@ -79,39 +77,40 @@ typedef struct quad_threadinfo_t
const long lowerBaseBitsQ1[] = // for quad-structure with quality 1 const long lowerBaseBitsQ1[] = // for quad-structure with quality 1
{ {
0x2aa4,0x3d96,0x60a6,0x8596 0x3f18,0x520a,0x751a,0x9a0a
}; };
const long lowerBaseBitsQ2[] = // for quad-structure with quality 2 const long lowerBaseBitsQ2[] = // for quad-structure with quality 2
{ {
0x0822,0x0bd4,0x0c74,0x0dd4,0x0dd6,0x0e54,0x1119,0x12b9,0x12be, 0x0770,0x0775,0x07ad,0x07b2,0x0c3a,0x0c58,0x0cba,0x0cd8,0x0e38,
0x12c5,0x12e4,0x12e9,0x1354,0x1355,0x1635,0x17c6,0x1846,0x1a44, 0x0e5a,0x0ed8,0x0eda,0x111c,0x1c96,0x2048,0x20e8,0x2248,0x224a,
0x1c18,0x1d92,0x22a6,0x241c,0x2896,0x2aa4,0x2bf4,0x2c56,0x2c74, 0x22c8,0x258d,0x272d,0x2732,0x2739,0x2758,0x275d,0x27c8,0x27c9,
0x2d16,0x2dd4,0x2df6,0x2e76,0x32be,0x32c4,0x32c5,0x32f1,0x32f4, 0x2aa9,0x2c3a,0x2cba,0x2eb8,0x308c,0x3206,0x371a,0x3890,0x3d0a,
0x32f6,0x333c,0x3341,0x3360,0x3365,0x3374,0x37e4,0x39c4,0x3a44, 0x3f18,0x4068,0x40ca,0x40e8,0x418a,0x4248,0x426a,0x42ea,0x4732,
0x3a66,0x3ca4,0x3d96,0x41a4,0x44a4,0x44a9,0x4594,0x49a4,0x4aa8, 0x4738,0x4739,0x4765,0x4768,0x476a,0x47b0,0x47b5,0x47d4,0x47d9,
0x4c56,0x52c5,0x52d4,0x52d5,0x52e4,0x5302,0x5340,0x5345,0x5355, 0x47e8,0x4c58,0x4e38,0x4eb8,0x4eda,0x5118,0x520a,0x5618,0x5918,
0x5364,0x5369,0x5378,0x57c6,0x57e4,0x5846,0x5926,0x59e6,0x5a64, 0x591d,0x5a08,0x5e18,0x5f1c,0x60ca,0x6739,0x6748,0x6749,0x6758,
0x5a66,0x5c94,0x5d06,0x60a6,0x61a4,0x64a8,0x6bf4,0x6d12,0x6dd4, 0x6776,0x67b4,0x67b9,0x67c9,0x67d8,0x67dd,0x67ec,0x6c3a,0x6c58,
0x6dd6,0x6e54,0x6e76,0x72bc,0x72c5,0x72d4,0x72f4,0x7345,0x7355, 0x6cba,0x6d9a,0x6e5a,0x6ed8,0x6eda,0x7108,0x717a,0x751a,0x7618,
0x735a,0x7365,0x7519,0x77c6,0x7866,0x79c4,0x7a44,0x80aa,0x82a4, 0x791c,0x8068,0x8186,0x8248,0x824a,0x82c8,0x82ea,0x8730,0x8739,
0x8596,0x8bd6,0x8bf4,0x8c56,0x8c74,0x8d16,0x8df6,0x8e74,0x8e76, 0x8748,0x8768,0x87b9,0x87c9,0x87ce,0x87d9,0x898d,0x8c3a,0x8cda,
0x8fc9,0x906d,0x9115,0x92f9,0x9338,0x933d,0x9379,0x93e9,0x93f9, 0x8e38,0x8eb8,0x951e,0x9718,0x9a0a,0xa04a,0xa068,0xa0ca,0xa0e8,
0x95b9,0x9d84,0x9da3,0xa584,0xa595,0xa5a3,0xa69b,0xb0d8,0xb285, 0xa18a,0xa26a,0xa2e8,0xa2ea,0xa43d,0xa4e1,0xa589,0xa76d,0xa7ac,
0xb4e0,0xb55a,0xc297,0xc2a5,0xc7e1,0xca97,0xcd50,0xd0e2,0xd115, 0xa7b1,0xa7ed,0xa85d,0xa86d,0xaa2d,0xb1f8,0xb217,0xb9f8,0xba09,
0xd5e9,0xf2fc,0xf301,0xf339,0xf33e,0xf7c6,0xf7e4,0xf846,0xf864, 0xba17,0xbb0f,0xc54c,0xc6f9,0xc954,0xc9ce,0xd70b,0xd719,0xdc55,
0xf9c4,0xf9e6,0xfa64,0xfa66,0xfca8 0xdf0b,0xe1c4,0xe556,0xe589,0xea5d
}; };
int isQuadWitchHutBase(const long seed, const long lower, const long upper) int isQuadFeatureBase(const long structureSeed, const long seed,
const long lower, const long upper)
{ {
// seed offsets for the regions (0,0) to (1,1) // seed offsets for the regions (0,0) to (1,1)
const long reg00base = 14357620; const long reg00base = structureSeed;
const long reg01base = 341873128712 + 14357620; const long reg01base = 341873128712 + structureSeed;
const long reg10base = 132897987541 + 14357620; const long reg10base = 132897987541 + structureSeed;
const long reg11base = 341873128712 + 132897987541 + 14357620; const long reg11base = 341873128712 + 132897987541 + structureSeed;
long s; long s;
@ -143,13 +142,14 @@ int isQuadWitchHutBase(const long seed, const long lower, const long upper)
} }
int isTriWitchHutBase(const long seed, const long lower, const long upper) int isTriFeatureBase(const long structureSeed, const long seed,
const long lower, const long upper)
{ {
// seed offsets for the regions (0,0) to (1,1) // seed offsets for the regions (0,0) to (1,1)
const long reg00base = 14357620; const long reg00base = structureSeed;
const long reg01base = 341873128712 + 14357620; const long reg01base = 341873128712 + structureSeed;
const long reg10base = 132897987541 + 14357620; const long reg10base = 132897987541 + structureSeed;
const long reg11base = 341873128712 + 132897987541 + 14357620; const long reg11base = 341873128712 + 132897987541 + structureSeed;
long s; long s;
int missing = 0; int missing = 0;
@ -191,7 +191,7 @@ int isTriWitchHutBase(const long seed, const long lower, const long upper)
return 1; return 1;
} }
long moveTemple(const long baseSeed, const int regionX, const int regionZ) long moveStructure(const long baseSeed, const int regionX, const int regionZ)
{ {
return (baseSeed - regionX*341873128712 - regionZ*132897987541) & 0xffffffffffff; return (baseSeed - regionX*341873128712 - regionZ*132897987541) & 0xffffffffffff;
} }
@ -200,10 +200,10 @@ long moveTemple(const long baseSeed, const int regionX, const int regionZ)
int isQuadMonumentBase(const long seed, const int qual) int isQuadMonumentBase(const long 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 long reg00base = 10387313; const long reg00base = MONUMENT_SEED;
const long reg01base = 341873128712 + 10387313; const long reg01base = 341873128712 + MONUMENT_SEED;
const long reg10base = 132897987541 + 10387313; const long reg10base = 132897987541 + MONUMENT_SEED;
const long reg11base = 341873128712 + 132897987541 + 10387313; const long reg11base = 341873128712 + 132897987541 + MONUMENT_SEED;
long s, p; long s, p;
@ -285,10 +285,10 @@ int isQuadMonumentBase(const long seed, const int qual)
int isTriMonumentBase(const long seed, const int qual) int isTriMonumentBase(const long 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 long reg00base = 10387313; const long reg00base = MONUMENT_SEED;
const long reg01base = 341873128712 + 10387313; const long reg01base = 341873128712 + MONUMENT_SEED;
const long reg10base = 132897987541 + 10387313; const long reg10base = 132897987541 + MONUMENT_SEED;
const long reg11base = 341873128712 + 132897987541 + 10387313; const long reg11base = 341873128712 + 132897987541 + MONUMENT_SEED;
long s, p; long s, p;
int incomplete = 0; int incomplete = 0;
@ -491,7 +491,7 @@ long *loadSavedSeeds(const char *fnam, long *scnt)
} }
static void *baseQuadWitchHutSearchThread(void *data) static void *search4QuadBasesThread(void *data)
{ {
quad_threadinfo_t info = *(quad_threadinfo_t*)data; quad_threadinfo_t info = *(quad_threadinfo_t*)data;
@ -499,35 +499,41 @@ static void *baseQuadWitchHutSearchThread(void *data)
const long upper = 23-info.quality; const long upper = 23-info.quality;
const long start = info.start; const long start = info.start;
const long end = info.end; const long end = info.end;
const long structureSeed = info.structureSeed;
long seed; long seed;
const long *lowerBits; long *lowerBits;
int lowerBitsCnt; int lowerBitsCnt;
int lowerBitsIdx = 0; int lowerBitsIdx = 0;
int i;
lowerBits = (long *) malloc(0x10000 * sizeof(long));
if(info.quality == 1) if(info.quality == 1)
{ {
lowerBits = &lowerBaseBitsQ1[0];
lowerBitsCnt = sizeof(lowerBaseBitsQ1) / sizeof(lowerBaseBitsQ1[0]); lowerBitsCnt = sizeof(lowerBaseBitsQ1) / sizeof(lowerBaseBitsQ1[0]);
for(i = 0; i < lowerBitsCnt; i++)
{
lowerBits[i] = (lowerBaseBitsQ1[i] - structureSeed) & 0xffff;
}
} }
else if(info.quality == 2) else if(info.quality == 2)
{ {
lowerBits = &lowerBaseBitsQ2[0];
lowerBitsCnt = sizeof(lowerBaseBitsQ2) / sizeof(lowerBaseBitsQ2[0]); lowerBitsCnt = sizeof(lowerBaseBitsQ2) / sizeof(lowerBaseBitsQ2[0]);
for(i = 0; i < lowerBitsCnt; i++)
{
lowerBits[i] = (lowerBaseBitsQ2[i] - structureSeed) & 0xffff;
}
} }
else else
{ {
printf("WARN baseQuadWitchHutSearchThread: " printf("WARN search4QuadBasesThread: "
"Lower bits for quality %d have not been defined => " "Lower bits for quality %d have not been defined => "
"will try all combinations.\n", info.quality); "will try all combinations.\n", info.quality);
static long lowerBaseBitsAll[65536]; lowerBitsCnt = 0x10000;
lowerBits = &lowerBaseBitsAll[0]; for(i = 0; i < lowerBitsCnt; i++) lowerBits[i] = i;
lowerBitsCnt = sizeof(lowerBaseBitsAll) / sizeof(lowerBaseBitsAll[0]);
int i;
for(i = 0; i < 65536; i++) lowerBaseBitsAll[i] = i;
} }
char fnam[256]; char fnam[256];
@ -536,6 +542,7 @@ static void *baseQuadWitchHutSearchThread(void *data)
FILE *fp = fopen(fnam, "a+"); FILE *fp = fopen(fnam, "a+");
if (fp == NULL) { if (fp == NULL) {
fprintf(stderr, "Could not open \"%s\" for writing.\n", fnam); fprintf(stderr, "Could not open \"%s\" for writing.\n", fnam);
free(lowerBits);
exit(-1); exit(-1);
} }
@ -572,7 +579,7 @@ static void *baseQuadWitchHutSearchThread(void *data)
while(seed < end) while(seed < end)
{ {
if(isQuadWitchHutBase(seed, lower, upper)) if(isQuadFeatureBase(structureSeed, seed, lower, upper))
{ {
fprintf(fp, "%ld\n", seed); fprintf(fp, "%ld\n", seed);
fflush(fp); fflush(fp);
@ -589,12 +596,14 @@ static void *baseQuadWitchHutSearchThread(void *data)
} }
fclose(fp); fclose(fp);
free(lowerBits);
return NULL; return NULL;
} }
void baseQuadWitchHutSearch(const char *fnam, const int threads, const int quality) void search4QuadBases(const char *fnam, const int threads,
const long structureSeed, const int quality)
{ {
pthread_t threadID[threads]; pthread_t threadID[threads];
quad_threadinfo_t info[threads]; quad_threadinfo_t info[threads];
@ -607,11 +616,12 @@ void baseQuadWitchHutSearch(const char *fnam, const int threads, const int quali
info[t].end = ((info[t].start + (SEEDMAX-1) / threads) & 0x0000ffffffff0000) + 1; info[t].end = ((info[t].start + (SEEDMAX-1) / threads) & 0x0000ffffffff0000) + 1;
info[t].fnam = fnam; info[t].fnam = fnam;
info[t].quality = quality; info[t].quality = quality;
info[t].structureSeed = structureSeed;
} }
for(t = 0; t < threads; t++) for(t = 0; t < threads; t++)
{ {
pthread_create(&threadID[t], NULL, baseQuadWitchHutSearchThread, (void*)&info[t]); pthread_create(&threadID[t], NULL, search4QuadBasesThread, (void*)&info[t]);
} }
for(t = 0; t < threads; t++) for(t = 0; t < threads; t++)
@ -639,7 +649,7 @@ void baseQuadWitchHutSearch(const char *fnam, const int threads, const int quali
if(fpart == NULL) if(fpart == NULL)
{ {
perror("ERR baseQuadWitchHutSearch: "); perror("ERR search4QuadBases: ");
break; break;
} }
@ -647,7 +657,7 @@ void baseQuadWitchHutSearch(const char *fnam, const int threads, const int quali
{ {
if(!fwrite(buffer, sizeof(char), n, fp)) if(!fwrite(buffer, sizeof(char), n, fp))
{ {
perror("ERR baseQuadWitchHutSearch: "); perror("ERR search4QuadBases: ");
fclose(fp); fclose(fp);
fclose(fpart); fclose(fpart);
return; return;
@ -669,7 +679,7 @@ void baseQuadWitchHutSearch(const char *fnam, const int threads, const int quali
/* getBiomeAtPos /* getBiomeAtPos
* ---------------- * -------------
* Returns the biome for the specified block position. * Returns the biome for the specified block position.
* (Alternatives should be considered in performance critical code.) * (Alternatives should be considered in performance critical code.)
* This function is not threadsafe. * This function is not threadsafe.
@ -683,17 +693,19 @@ int getBiomeAtPos(const LayerStack g, const Pos pos)
return ints[0]; return ints[0];
} }
/* getWitchHutPos /* getStructurePos
* ------------ * ---------------
* Fast implementation for finding the block position at which the witch hut * Fast implementation for finding the block position at which the structure
* generation attempt will occur in the specified region. * generation attempt will occur in the specified region.
* This function applies for scattered-feature structureSeeds and villages.
*/ */
Pos getWitchHutPos(long seed, const long regionX, const long regionZ) Pos getStructurePos(const long structureSeed, long seed, const long regionX,
const long regionZ)
{ {
Pos pos; Pos pos;
// set seed // set seed
seed = regionX*341873128712 + regionZ*132897987541 + seed + 14357620; seed = regionX*341873128712 + regionZ*132897987541 + seed + structureSeed;
seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1); seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1);
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff; seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
@ -708,16 +720,18 @@ Pos getWitchHutPos(long seed, const long regionX, const long regionZ)
} }
/* getWitchHutChunkInRegion /* getStructureChunkInRegion
* ---------------------- * -------------------------
* Finds the chunk position within the specified region (32x32 chunks) where * Finds the chunk position within the specified region (32x32 chunks) where
* the witch hut generation attempt will occur. * the structure generation attempt will occur.
* This function applies for scattered-feature structureSeeds and villages.
*/ */
Pos getWitchHutChunkInRegion(long seed, const int regionX, const int regionZ) Pos getStructureChunkInRegion(const long structureSeed, long seed,
const int regionX, const int regionZ)
{ {
/* /*
// Vanilla like implementation. // Vanilla like implementation.
seed = regionX*341873128712 + regionZ*132897987541 + seed + 14357620; seed = regionX*341873128712 + regionZ*132897987541 + seed + structureSeed;
setSeed(&(seed)); setSeed(&(seed));
Pos pos; Pos pos;
@ -727,7 +741,7 @@ Pos getWitchHutChunkInRegion(long seed, const int regionX, const int regionZ)
Pos pos; Pos pos;
// set seed // set seed
seed = regionX*341873128712 + regionZ*132897987541 + seed + 14357620; seed = regionX*341873128712 + regionZ*132897987541 + seed + structureSeed;
seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1); seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1);
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff; seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
@ -740,30 +754,6 @@ Pos getWitchHutChunkInRegion(long seed, const int regionX, const int regionZ)
} }
/* getVillagePos
* -------------
* Fast implementation for finding the block position at which the village
* generation attempt will occur in the specified region.
*/
Pos getVillagePos(long seed, const long regionX, const long regionZ)
{
Pos pos;
// set seed
seed = regionX*341873128712 + regionZ*132897987541 + seed + 10387312;
seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1);
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
pos.x = (seed >> 17) % 24;
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
pos.z = (seed >> 17) % 24;
pos.x = regionX*512 + (pos.x << 4) + 8;
pos.z = regionZ*512 + (pos.z << 4) + 8;
return pos;
}
/* getOceanMonumentPos /* getOceanMonumentPos
* ------------------- * -------------------
@ -775,7 +765,7 @@ Pos getOceanMonumentPos(long seed, const long regionX, const long regionZ)
Pos pos; Pos pos;
// set seed // set seed
seed = regionX*341873128712 + regionZ*132897987541 + seed + 10387313; seed = regionX*341873128712 + regionZ*132897987541 + seed + MONUMENT_SEED;
seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1); seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff; seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
@ -808,7 +798,7 @@ Pos getMansionPos(long seed, const long area80X, const long area80Z)
Pos pos; Pos pos;
// set seed // set seed
seed = area80X*341873128712 + area80Z*132897987541 + seed + 10387319; seed = area80X*341873128712 + area80Z*132897987541 + seed + MANSION_SEED;
seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1); seed = (seed ^ 0x5DEECE66DL);// & ((1L << 48) - 1);
seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff; seed = (seed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff;
@ -1060,15 +1050,16 @@ int areBiomesViable(
int isViableTemplePos(const LayerStack g, int *cache, const long blockX, const long blockZ) int isViableFeaturePos(const LayerStack g, int *cache, const long blockX, const long blockZ)
{ {
static int map[0x100]; static int map[0x100];
genArea(&g.layers[L_VORONOI_ZOOM_1], map, blockX, blockZ, 1, 1); genArea(&g.layers[L_VORONOI_ZOOM_1], map, blockX, blockZ, 1, 1);
if(map[0] == jungle || map[0] == jungleHills) return JUNGLE_TEMPLE; if(map[0] == jungle || map[0] == jungleHills) return Jungle_Pyramid;
if(map[0] == swampland) return SWAMP_HUT; if(map[0] == swampland) return Swamp_Hut;
if(map[0] == icePlains || map[0] == coldTaiga) return IGLOO; if(map[0] == icePlains || map[0] == coldTaiga) return Igloo;
if(map[0] == desert || map[0] == desertHills) return DESERT_TEMPLE; if(map[0] == desert || map[0] == desertHills) return Desert_Pyramid;
if(isOceanic(map[0])) return Ocean_Ruin;
return 0; return 0;
} }

View File

@ -11,7 +11,19 @@
#define THREADS 6 #define THREADS 6
#define SEEDMAX (1L << 48) #define SEEDMAX (1L << 48)
enum {SWAMP_HUT = 1, IGLOO, DESERT_TEMPLE, JUNGLE_TEMPLE}; #define FEATURE_SEED 14357617
#define VILLAGE_SEED 10387312
#define MONUMENT_SEED 10387313
#define MANSION_SEED 10387319
/* 1.13 separated feature seeds by type */
#define DESERT_PYRAMID_SEED 14357617
#define IGLOO_SEED 14357618
#define JUNGLE_PYRAMID_SEED 14357619
#define SWAMP_HUT_SEED 14357620
#define OCEAN_RUIN_SEED 14357621
enum {Desert_Pyramid=1, Igloo, Jungle_Pyramid, Swamp_Hut, Ocean_Ruin};
static const int templeBiomeList[] = {desert, desertHills, jungle, jungleHills, swampland, icePlains, coldTaiga}; static const int templeBiomeList[] = {desert, desertHills, jungle, jungleHills, swampland, icePlains, coldTaiga};
static const int biomesToSpawnIn[] = {forest, plains, taiga, taigaHills, forestHills, jungle, jungleHills}; static const int biomesToSpawnIn[] = {forest, plains, taiga, taigaHills, forestHills, jungle, jungleHills};
@ -29,7 +41,6 @@ static const int achievementBiomes[] =
STRUCT(Pos) STRUCT(Pos)
{ {
int x, z; int x, z;
@ -60,17 +71,14 @@ extern Biome biomes[256];
* *
* Minecraft uses a 48-bit pseudo random number generator (PRNG) to determine * Minecraft uses a 48-bit pseudo random number generator (PRNG) to determine
* the position of it's structures. The remaining top 16 bits do not influence * the position of it's structures. The remaining top 16 bits do not influence
* the structure positioning. Additionally the position of all temples in a * the structure positioning. Additionally the position of most structures in a
* world can be translated by applying the following transformation to the * world can be translated by applying the following transformation to the
* seed: * seed:
* *
* seed2 = seed1 - structureSeed - dregX * 341873128712 - dregZ * 132897987541; * seed2 = seed1 - dregX * 341873128712 - dregZ * 132897987541;
* *
* Here seed1 and seed2 have the same structure positioning, but moved by a * Here seed1 and seed2 have the same structure positioning, but moved by a
* region offset of (dregX,dregZ). [a region is 32x32 chunks]. The value of * region offset of (dregX,dregZ). [a region is 32x32 chunks].
* structureSeed depends on the type of structure, 14357617 for desert temples,
* 14357618 for igloos, 14357619 for jungle temples and 14357620 for witch
* huts.
* *
* For a quad-structure, we mainly care about relative positioning, so we can * For a quad-structure, we mainly care about relative positioning, so we can
* get away with just checking the regions near the origin: (0,0),(0,1),(1,0) * get away with just checking the regions near the origin: (0,0),(0,1),(1,0)
@ -90,16 +98,19 @@ extern Biome biomes[256];
* degrees of freedom for region-transposition, and the top 16-bit bits). * degrees of freedom for region-transposition, and the top 16-bit bits).
*/ */
// helper functions
int isQuadWitchHutBase(const long seed, const long lower, const long upper);
int isTriWitchHutBase(const long seed, const long lower, const long upper);
/* moveTemple // helper functions
* ---------- int isQuadFeatureBase(const long structureSeed, const long seed,
const long lower, const long upper);
int isTriFeatureBase(const long structureSeed, const long seed,
const long lower, const long upper);
/* moveStructure
* -------------
* Transposes a base seed such that structures are moved by the specified region * Transposes a base seed such that structures are moved by the specified region
* vector, (regX, regZ). * vector, (regX, regZ).
*/ */
long moveTemple(const long baseSeed, const int regX, const int regZ); long moveStructure(const long baseSeed, const int regX, const int regZ);
/* loadSavedSeeds /* loadSavedSeeds
* -------------- * --------------
@ -113,12 +124,13 @@ long moveTemple(const long baseSeed, const int regX, const int regZ);
*/ */
long *loadSavedSeeds(const char *fnam, long *scnt); long *loadSavedSeeds(const char *fnam, long *scnt);
/* baseQuadWitchHutSearch /* search4QuadBases
* -------------------- * ----------------
* Starts a multi-threaded search for quad-temple base seeds of the specified * Starts a multi-threaded search for structure base seeds of the specified
* quality (chunk tolerance). The result is saved in a file of path 'fnam'. * quality (chunk tolerance). The result is saved in a file of path 'fnam'.
*/ */
void baseQuadWitchHutSearch(const char *fnam, int threads, int quality); void search4QuadBases(const char *fnam, int threads, const long structureSeed,
int quality);
@ -134,27 +146,25 @@ void baseQuadWitchHutSearch(const char *fnam, int threads, int quality);
int getBiomeAtPos(const LayerStack g, const Pos pos); int getBiomeAtPos(const LayerStack g, const Pos pos);
/* getWitchHutChunkInRegion /* getStructureChunkInRegion
* ---------------------- * -------------------------
* Finds the chunk position within the specified region (32x32 chunks) where * Finds the chunk position within the specified region (32x32 chunks) where
* the temple generation attempt will occur. * the structure generation attempt will occur.
* This function applies for scattered-feature structureSeeds and villages.
*/ */
Pos getWitchHutChunkInRegion(long seed, const int regionX, const int regionZ); Pos getStructureChunkInRegion(const long structureSeed, long seed,
const int regionX, const int regionZ);
/* getWitchHutPos /* getStructurePos
* ------------ * ---------------
* Fast implementation for finding the block position at which the temple * Fast implementation for finding the block position at which the structure
* generation attempt will occur in the specified region. * generation attempt will occur in the specified region.
* This function applies for scattered-feature structureSeeds and villages.
*/ */
Pos getWitchHutPos(long seed, const long regionX, const long regionZ); Pos getStructurePos(const long structureSeed, long seed, const long regionX,
const long regionZ);
/* getVillagePos
* -------------
* Fast implementation for finding the block position at which the village
* generation attempt will occur in the specified region.
*/
Pos getVillagePos(long seed, const long regionX, const long regionZ);
/* getOceanMonumentPos /* getOceanMonumentPos
* ------------------- * -------------------

View File

@ -868,8 +868,7 @@ void mapHills(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidt
int pWidth = areaWidth + 2; int pWidth = areaWidth + 2;
int pHeight = areaHeight + 2; int pHeight = areaHeight + 2;
int x, z; int x, z;
static int bufsize = 0; int *buf = NULL;
static int *buf = NULL;
if(l->p2 == NULL) if(l->p2 == NULL)
{ {

View File

@ -383,6 +383,7 @@ void mapRareBiome(Layer *l, int * __restrict out, int x, int z, int w, int h);
void mapShore(Layer *l, int * __restrict out, int x, int z, int w, int h); void mapShore(Layer *l, int * __restrict out, int x, int z, int w, int h);
void mapRiverMix(Layer *l, int * __restrict out, int x, int z, int w, int h); void mapRiverMix(Layer *l, int * __restrict out, int x, int z, int w, int h);
// TODO: 1.13 updated again and these functions are outdated!
void mapOceanTemp(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight); void mapOceanTemp(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);
void mapEdgeOcean(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight); void mapEdgeOcean(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);
void mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight); void mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);

View File

@ -1,11 +1,15 @@
CC = gcc CC = gcc
LDFLAGS = -lm -pthread LDFLAGS = -lm -pthread
override CFLAGS += -O3 -Wall -fwrapv -march=native override CFLAGS += -Wall -fwrapv -march=native
.PHONY : all clean .PHONY : all debug clean
all: CFLAGS += -O3
all: find_quadhuts find_compactbiomes clean all: find_quadhuts find_compactbiomes clean
debug: CFLAGS += -DDEBUG -O0 -g
debug: find_quadhuts find_compactbiomes clean
find_compactbiomes: find_compactbiomes.o layers.o generator.o finders.o find_compactbiomes: find_compactbiomes.o layers.o generator.o finders.o
$(CC) -o $@ $^ $(LDFLAGS) $(CC) -o $@ $^ $(LDFLAGS)

107959
seeds/quadhutbases_1_7_Q1.txt Normal file

File diff suppressed because it is too large Load Diff