diff --git a/finders.c b/finders.c index adfd521..b0ea6e6 100644 --- a/finders.c +++ b/finders.c @@ -75,7 +75,8 @@ void setAttemptSeed(int64_t *s, int cx, int cz) next(s, 31); } -int getConfig(int structureType, int mc, StructureConfig *sconf) + +int getStructureConfig(int structureType, int mc, StructureConfig *sconf) { switch (structureType) { @@ -136,8 +137,14 @@ int getConfig(int structureType, int mc, StructureConfig *sconf) int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ, Pos *pos) { StructureConfig sconf; - if (!getConfig(structureType, mc, &sconf)) +#if STRUCT_CONFIG_OVERRIDE + if (!getStructureConfig_override(structureType, mc, &sconf)) +#else + if (!getStructureConfig(structureType, mc, &sconf)) +#endif + { return 0; + } switch (structureType) { @@ -170,7 +177,9 @@ int getStructurePos(int structureType, int mc, int64_t seed, int regX, int regZ, case Treasure: pos->x = (regX << 4) + 9; pos->z = (regZ << 4) + 9; - return isTreasureChunk(seed, regX, regZ); + seed = regX*341873128712 + regZ*132897987541 + seed + sconf.salt; + setSeed(&seed, seed); + return nextFloat(&seed) < 0.01; case Fortress: if (mc < MC_1_16) { @@ -211,14 +220,6 @@ int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ) return nextDouble(&s) < 0.004; } -int isTreasureChunk(int64_t seed, int chunkX, int chunkZ) -{ - seed = chunkX*341873128712 + chunkZ*132897987541 + seed + TREASURE_CONFIG.salt; - setSeed(&seed, seed); - return nextFloat(&seed) < 0.01; -} - - //============================================================================== // Multi-Structure Checks @@ -1427,13 +1428,13 @@ int isViableFeatureBiome(int mc, int structureType, int biomeID) case Fortress: return (biomeID == nether_wastes || biomeID == soul_sand_valley || - biomeID == warped_forest || biomeID == crimson_forest); + biomeID == warped_forest || biomeID == crimson_forest || + biomeID == basalt_deltas); case Bastion: if (mc < MC_1_16) return 0; return (biomeID == nether_wastes || biomeID == soul_sand_valley || - biomeID == warped_forest || biomeID == crimson_forest || - biomeID == basalt_deltas); + biomeID == warped_forest || biomeID == crimson_forest); case End_City: if (mc < MC_1_9) return 0; @@ -1788,8 +1789,10 @@ L_not_viable: int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn, int64_t seed, int blockX, int blockZ) { + if (structureType == Fortress) + return 1; // fortresses generate in all nether biomes and mc versions if (mc < MC_1_16) - return structureType == Fortress; + return 0; blockX = ((blockX >> 4) << 2) + 2; blockZ = ((blockZ >> 4) << 2) + 2; diff --git a/finders.h b/finders.h index 2b6e9e3..eaf7dd3 100644 --- a/finders.h +++ b/finders.h @@ -270,7 +270,17 @@ int64_t *loadSavedSeeds(const char *fnam, int64_t *scnt); /* Selects the structure configuration for a given version. Returns zero upon * failure (e.g. version does not support structure type). */ -int getConfig(int structureType, int mc, StructureConfig *sconf); +int getStructureConfig(int structureType, int mc, StructureConfig *sconf); + +/* The library can be compiled to use a custom internal getter for structure + * configurations. For this, the macro STRUCT_CONFIG_OVERRIDE should be defined + * as true and the function getStructureConfig_override() should be defined + * with a custom function body. However, note this is experimental and not all + * structure configs may work. (Ideally only change structure salts.) + */ +#if STRUCT_CONFIG_OVERRIDE +int getStructureConfig_override(int stype, int mc, StructureConfig *sconf); +#endif /* Finds the block position of the structure generation attempt in a given * region. You can use isViableStructurePos() to test if the necessary biome @@ -310,7 +320,6 @@ Pos getLargeStructureChunkInRegion(StructureConfig config, int64_t seed, int reg * or at (2,2) with layer scale=4 from 1.16 onwards. */ int isMineshaftChunk(int64_t seed, int chunkX, int chunkZ); -int isTreasureChunk(int64_t seed, int chunkX, int chunkZ); // not exacly a structure static inline __attribute__((const)) diff --git a/generator.c b/generator.c index 1ea0bfb..da89f78 100644 --- a/generator.c +++ b/generator.c @@ -271,13 +271,13 @@ int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, i int genNetherScaled(int mc, int64_t seed, int scale, int *out, int x, int z, int w, int h, int y0, int y1) { - if (!scale || (scale & (scale-1)) || (scale & ~0x55)) - return 1; // scale is not a power of 4 <= 64 + if (scale != 1 && scale != 4 && scale != 16 && scale != 64) + return 1; // unsupported scale if (mc < MC_1_16) { - int siz = w*h*(y1-y0+1); - for (int i = 0; i < siz; i++) + int i, siz = w*h*(y1-y0+1); + for (i = 0; i < siz; i++) out[i] = nether_wastes; return 0; } @@ -303,13 +303,13 @@ int genNetherScaled(int mc, int64_t seed, int scale, int *out, int err = mapNether2D(&nn, out, pX, pZ, pW, pH); if (err) return err; - Layer lvoronoi = {}; + Layer lvoronoi = {0}; lvoronoi.startSalt = getVoronoiSHA(seed); return mapVoronoi(&lvoronoi, out, x, z, w, h); } else { - return mapNether3D(&nn, out, x, z, w, h, y0, y1+1, scale, 1.0); + return mapNether3D(&nn, out, x, z, w, h, y0, y1-y0+1, scale, 1.0); } } @@ -317,13 +317,13 @@ int genNetherScaled(int mc, int64_t seed, int scale, int *out, int genEndScaled(int mc, int64_t seed, int scale, int *out, int x, int z, int w, int h) { - if (!scale || (scale & (scale-1)) || (scale & ~0x55)) - return 1; // scale is not a power of 4 <= 64 + if (scale != 1 && scale != 4 && scale != 16 && scale != 64) + return 1; // unsupported scale if (mc < MC_1_9) { - int siz = w*h; - for (int i = 0; i < siz; i++) + int i, siz = w*h; + for (i = 0; i < siz; i++) out[i] = the_end; return 0; } @@ -343,7 +343,7 @@ int genEndScaled(int mc, int64_t seed, int scale, int *out, int err = mapEnd(&en, out, pX, pZ, pW, pH); if (err) return err; - Layer lvoronoi = {}; + Layer lvoronoi = {0}; if (mc >= MC_1_15) { lvoronoi.startSalt = getVoronoiSHA(seed);