added 1.13 biome generator

This commit is contained in:
Cubitect 2018-03-10 21:45:57 +00:00
parent c26e57a1ce
commit 4db50a4e6d
6 changed files with 555 additions and 119 deletions

167
finders.c
View File

@ -426,6 +426,120 @@ Pos getTempleChunkInRegion(long seed, int regionX, int regionZ)
}
/* findBiomePosition
* -----------------
* Finds a suitable pseudo-random location in the specified area.
* Used to determine the positions of spawn and stongholds.
* The return value is non-zero if a valid location was found.
* Warning: accurate, but slow!
*
* TODO: Spawn finding not working in 1.10
*/
int findBiomePosition(Generator *g, Pos *out, int centerX, int centerZ, int range, const int *biomeList, long *seed)
{
int x1 = (centerX-range) >> 2;
int z1 = (centerZ-range) >> 2;
int x2 = (centerX+range) >> 2;
int z2 = (centerZ+range) >> 2;
int width = x2 - x1 + 1;
int height = z2 - z1 + 1;
int *map = allocCache(g, width, height);
genArea(g, map, x1, z1, width, height);
int i, found = 0;
out->x = 0;
out->z = 0;
for(i = 0; i < width*height; i++)
{
int biome = map[i];
if(biomeList[biome & 0xff] && (found == 0 || nextInt(seed, found + 1) == 0))
{
out->x = (x1 + i%width) << 2;
out->z = (z1 + i/width) << 2;
++found;
}
}
free(map);
return found;
}
/*s
Pos getSpawn(long seed)
{
Generator g = setupGenerator();
g.topLayerIndex = 43;
applySeed(g, seed);
Pos spawn;
setSeed(&seed);
int found = findBiomePosition(&g, &spawn, 0, 0, 256, biomesToSpawnIn, &seed);
if(!found)
{
//printf("Unable to find spawn biome");
}
int var9 = 0;
while (!this.provider.canCoordinateBeSpawn(var6, var8))
{
var6 += var4.nextInt(64) - var4.nextInt(64);
var8 += var4.nextInt(64) - var4.nextInt(64);
++var9;
if (var9 == 1000)
{
break;
}
}
}
*/
/* areBiomesViable
* ---------------
* Determines if the given area contains only biomes specified by 'biomeList'.
* Used to determine the positions of ocean monuments and villages.
* Warning: accurate, but slow!
*/
int areBiomesViable(Generator *g, int posX, int posZ, int radius, const int *biomeList, const int listLen)
{
int x1 = (posX - radius) >> 2;
int z1 = (posZ - radius) >> 2;
int x2 = (posX + radius) >> 2;
int z2 = (posZ + radius) >> 2;
int width = x2 - x1 + 1;
int height = z2 - z1 + 1;
int i, j;
int *map = allocCache(g, width, height);
genArea(g, map, x1, z1, width, height);
for(i = 0; i < width*height; i++)
{
for(j = 0; j < listLen; j++)
{
if(map[i] == biomeList[j]) break;
}
if(j >= listLen)
{
free(map);
return 0;
}
}
free(map);
return 1;
}
/* filterAllTempCats
* -----------------
@ -677,4 +791,57 @@ long filterAllMajorBiomes(long *seedsIn, long *seedsOut, long seedCnt,
// very slow!
int getAllBiomeRadius(long seed, const int startRadius)
{
Generator g = setupGenerator();
int x, z, r, i, bnum;
int *map;
int blist[BIOME_NUM];
map = allocCache(&g, startRadius*2+1, startRadius*2+1);
applySeed(&g, seed);
genArea(&g, map, -startRadius, -startRadius, startRadius*2, startRadius*2);
for(r = startRadius; r > 0; r--)
{
memset(blist, 0, sizeof(int)*BIOME_NUM);
for(z = startRadius-r; z < startRadius+r; z++)
{
for(x = startRadius-r; x < startRadius+r; x++)
{
blist[map[x + z*2*startRadius] & 0x7f] = 1;
}
}
for(i = 0, bnum = 0; i < BIOME_NUM; i++) if(blist[i]) bnum++;
if(bnum < 36) break;
}
free(map);
freeGenerator(&g);
return r+1;
}

View File

@ -5,14 +5,14 @@
#include <stdlib.h>
#include <string.h>
const int magscale[] = {1, 4, 16, 64, 256, 256, 1024 };
int *allocCache(Generator *g, int sizeX, int sizeZ)
{
int size = calcRequiredBuf(g, sizeX, sizeZ);
if(size < 256) size = 256;
int size = calcRequiredBuf(&g->layers[g->topLayerIndex-1], sizeX, sizeZ);
int *ret = (int*) malloc(sizeof(*ret)*size);
memset(ret, 0, sizeof(*ret)*size);
return ret;
}
@ -33,6 +33,11 @@ void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(Layer
}
Generator setupGenerator()
{
return setupGeneratorMC18();
}
Generator setupGeneratorMC18()
{
if(biomes[plains].id == 0)
{
@ -42,7 +47,6 @@ Generator setupGenerator()
Generator g;
g.rawSeed = 0;
g.mag = 1;
g.topLayerIndex = 44;
g.layerMax = 44;
g.layers = (Layer*) malloc(sizeof(Layer)*g.topLayerIndex);
@ -104,74 +108,151 @@ Generator setupGenerator()
return g;
}
void setGenScale(Generator *g, int magnification)
Generator setupGeneratorMC113()
{
switch(magnification)
if(biomes[plains].id == 0)
{
case MAG1:
g->mag = MAG1;
g->topLayerIndex = 44;
break;
case MAG4:
g->mag = MAG4;
g->topLayerIndex = 43;
break;
case MAG16:
g->mag = MAG16;
g->topLayerIndex = 39;
break;
case MAG64:
g->mag = MAG64;
g->topLayerIndex = 26;
break;
case MAG256:
g->mag = MAG256;
g->topLayerIndex = 19;
break;
case MAGSHROOM:
g->mag = MAGSHROOM;
g->topLayerIndex = 17;
break;
case MAG1024:
g->mag = MAG1024;
g->topLayerIndex = 11;
break;
fprintf(stderr, "Warning: The biomes have to be initialised first using initBiomes() before any generator can be used.\n");
}
Generator g;
g.rawSeed = 0;
g.topLayerIndex = 53;
g.layerMax = 53;
g.layers = (Layer*) malloc(sizeof(Layer)*g.topLayerIndex);
// LAYER PARENT SEED LAYER_FUNCTION
setupLayer(&g.layers[ 0], NULL, 1, mapIsland);
setupLayer(&g.layers[ 1], &g.layers[ 0], 2000, mapZoom);
setupLayer(&g.layers[ 2], &g.layers[ 1], 1, mapAddIsland);
setupLayer(&g.layers[ 3], &g.layers[ 2], 2001, mapZoom);
setupLayer(&g.layers[ 4], &g.layers[ 3], 2, mapAddIsland);
setupLayer(&g.layers[ 5], &g.layers[ 4], 50, mapAddIsland);
setupLayer(&g.layers[ 6], &g.layers[ 5], 70, mapAddIsland);
setupLayer(&g.layers[ 7], &g.layers[ 6], 2, mapRemoveTooMuchOcean);
setupLayer(&g.layers[ 8], &g.layers[ 7], 2, mapAddSnow);
setupLayer(&g.layers[ 9], &g.layers[ 8], 3, mapAddIsland);
setupLayer(&g.layers[10], &g.layers[ 9], 2, mapCoolWarm); // MAG1024
setupLayer(&g.layers[11], &g.layers[10], 2, mapHeatIce);
setupLayer(&g.layers[12], &g.layers[11], 3, mapSpecial);
setupLayer(&g.layers[13], &g.layers[12], 2002, mapZoom);
setupLayer(&g.layers[14], &g.layers[13], 2003, mapZoom);
setupLayer(&g.layers[15], &g.layers[14], 4, mapAddIsland);
setupLayer(&g.layers[16], &g.layers[15], 5, mapAddMushroomIsland); // MAGSHROOM
setupLayer(&g.layers[17], &g.layers[16], 4, mapDeepOcean);
// biome layer chain
setupLayer(&g.layers[18], &g.layers[17], 200, mapBiome); // MAG256
setupLayer(&g.layers[19], &g.layers[18], 1000, mapZoom);
setupLayer(&g.layers[20], &g.layers[19], 1001, mapZoom);
setupLayer(&g.layers[21], &g.layers[20], 1000, mapBiomeEdge);
// basic river layer chain, used to determine where hills generate
setupLayer(&g.layers[22], &g.layers[17], 100, mapRiverInit);
setupLayer(&g.layers[23], &g.layers[22], 1000, mapZoom);
setupLayer(&g.layers[24], &g.layers[23], 1001, mapZoom);
setupMultiLayer(&g.layers[25], &g.layers[21], &g.layers[24], 1000, mapHills); // MAG64
setupLayer(&g.layers[26], &g.layers[25], 1001, mapRareBiome);
setupLayer(&g.layers[27], &g.layers[26], 1000, mapZoom);
setupLayer(&g.layers[28], &g.layers[27], 3, mapAddIsland);
setupLayer(&g.layers[29], &g.layers[28], 1001, mapZoom);
setupLayer(&g.layers[30], &g.layers[29], 1000, mapShore);
setupLayer(&g.layers[31], &g.layers[30], 1002, mapZoom);
setupLayer(&g.layers[32], &g.layers[31], 1003, mapZoom);
setupLayer(&g.layers[33], &g.layers[32], 1000, mapSmooth);
// river layer chain
setupLayer(&g.layers[34], &g.layers[22], 1000, mapZoom);
setupLayer(&g.layers[35], &g.layers[34], 1001, mapZoom);
setupLayer(&g.layers[36], &g.layers[35], 1000, mapZoom);
setupLayer(&g.layers[37], &g.layers[36], 1001, mapZoom);
setupLayer(&g.layers[38], &g.layers[37], 1002, mapZoom); // MAG16
setupLayer(&g.layers[39], &g.layers[38], 1003, mapZoom);
setupLayer(&g.layers[40], &g.layers[39], 1, mapRiver);
setupLayer(&g.layers[41], &g.layers[40], 1000, mapSmooth);
setupMultiLayer(&g.layers[42], &g.layers[33], &g.layers[41], 100, mapRiverMix);
// ocean variants
// This branch is connected to layer 7, but makes no use of it (only size).
// I.e this branch is independent of previous layers.
setupLayer(&g.layers[43], &g.layers[ 7], 2, mapOceanTemp);
setupLayer(&g.layers[44], &g.layers[43], 2, mapEdgeOcean);
setupLayer(&g.layers[45], &g.layers[44], 2001, mapZoom);
setupLayer(&g.layers[46], &g.layers[45], 2002, mapZoom);
setupLayer(&g.layers[47], &g.layers[46], 2003, mapZoom);
setupLayer(&g.layers[48], &g.layers[47], 2004, mapZoom);
setupLayer(&g.layers[49], &g.layers[48], 2005, mapZoom);
setupLayer(&g.layers[50], &g.layers[49], 2006, mapZoom);
setupMultiLayer(&g.layers[51], &g.layers[42], &g.layers[50], 100, mapOceanMix);
setupLayer(&g.layers[52], &g.layers[51], 10, mapVoronoiZoom);
return g;
}
void setTopLevel(Generator *g, int topLevel)
{
if(topLevel > g->layerMax)
{
printf("Warning: Top layer index is greater than the number of layers in this generator.");
}
else
{
g->topLayerIndex = topLevel;
}
}
int calcRequiredBuf(Generator *g, int areaX, int areaZ)
static void getMaxArea(Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
{
areaX += 2;
areaZ += 2;
int i, maxX = areaX, maxZ = areaZ;
if(layer == NULL)
return;
for(i = g->topLayerIndex-1; i >= 0; i--)
if(layer->getMap == mapZoom)
{
if(g->layers[i].getMap == mapZoom)
areaX = (areaX >> 1) + 2;
areaZ = (areaZ >> 1) + 2;
}
else if(layer->getMap == mapVoronoiZoom)
{
areaX = (areaX >> 2) + 2;
areaZ = (areaZ >> 2) + 2;
}
else
{
if( layer->getMap != mapIsland &&
layer->getMap != mapSpecial &&
layer->getMap != mapBiome &&
layer->getMap != mapRiverInit &&
layer->getMap != mapRiverMix )
{
areaX = (areaX >> 1) + 2; areaZ = (areaZ >> 1) + 2;
}
else if(g->layers[i].getMap == mapVoronoiZoom)
{
areaX = (areaX >> 2) + 2; areaZ = (areaZ >> 2) + 2;
}
else
{
if(g->layers[i].getMap == mapIsland) continue;
if(g->layers[i].getMap == mapSpecial) continue;
if(g->layers[i].getMap == mapBiome) continue;
if(g->layers[i].getMap == mapRiverInit) continue;
if(g->layers[i].getMap == mapRiverMix) continue;
areaX += 2;
areaZ += 2;
}
if(areaX > maxX) maxX = areaX;
if(areaZ > maxZ) maxZ = areaZ;
}
return (2*maxX+2) * (2*maxZ+2);
if(areaX > *maxX) *maxX = areaX;
if(areaZ > *maxZ) *maxZ = areaZ;
getMaxArea(layer->p, areaX, areaZ, maxX, maxZ);
getMaxArea(layer->p2, areaX, areaZ, maxX, maxZ);
}
int calcRequiredBuf(Layer *layer, int areaX, int areaZ)
{
int maxX = areaX, maxZ = areaZ;
getMaxArea(layer, areaX, areaZ, &maxX, &maxZ);
return maxX * maxZ;
}
void freeGenerator(Generator *g)
@ -183,7 +264,7 @@ void applySeed(Generator *g, long seed)
{
g->rawSeed = seed;
// the seed has to be applied recursively, such that the branching layer chains (of parent 2) keep a world seed of zero
// the seed has to be applied recursively
setWorldSeed(&g->layers[g->topLayerIndex-1], seed);
}

View File

@ -3,48 +3,37 @@
#include "layers.h"
/* If speed is more important than accuracy, here are some magnification modes for the generator.
* The map generation is done in stages (layers), some of which zoom into the map, magnifying it.
* These magnification modes control at which stage/magnification the map generation is aborted.
*
* Notes on magnification modes:
* MAG1 - 1 to 1 scale, exact map of the biomes
* MAG4 - 1 to 4 scale, used by some vanilla mc-generation as a faster alternative to the full scale map
* MAG16 - 1 to 16 scale, contains all biomes, except rivers
* MAG64 - 1 to 64 scale, misses oceanic features like beaches, small islands and rare biomes (Sunflower Plains).
* MAG256 - 1 to 256 scale, contains all the basic biomes, no variations (e.g. no hills and no mutations).
* MAGSHROOM, 1 to 256 scale, exploits that Mushroom Islands are determined before most other biomes.
* MAG1024 - 1 to 1024 scale, extreme scale that only contains basic information where biome types generate.
*/
enum Magnification { MAG1, MAG4, MAG16, MAG64, MAG256, MAGSHROOM, MAG1024 };
extern const int magscale[];
STRUCT(Generator) {
Layer *layers;
int topLayerIndex;
int layerMax;
int mag;
long rawSeed;
};
// Initialise an instance of a generator
Generator setupGenerator();
Generator setupGeneratorMC18();
Generator setupGeneratorMC113();
// Sets the magnification mode of the generator
void setGenScale(Generator *g, int magnification);
// Sets the top level layer of a generator.
void setTopLevel(Generator *g, int topLevel);
// Cleans up and frees the generator layers
void freeGenerator(Generator *g);
// Allocates an amount of memory required to generate an area of dimensions 'sizeX' by 'sizeZ'
int *allocCache(Generator *g, int sizeX, int sizeZ);
// Allocates an amount of memory required to generate an area of dimensions
// 'sizeX' by 'sizeZ' for the magnification of the current top layer.
int *allocCache(Generator *layer, int sizeX, int sizeZ);
// 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 setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h));
// Calculates the minimum size of the buffers required to generate an area of dimensions 'sizeX' by 'sizeZ'
int calcRequiredBuf(Generator *g, int sizeX, int sizeZ);
// Calculates the minimum size of the buffers required to generate an area of dimensions
// 'sizeX' by 'sizeZ' at the scale of the layer.
int calcRequiredBuf(Layer *layer, int sizeX, int sizeZ);
// Sets the world seed for the generator
void applySeed(Generator *g, long seed);

235
layers.c
View File

@ -70,6 +70,19 @@ void initBiomes()
initAddBiome(mesaPlateau_F, Warm, Mesa, 2.0, hHighPlateaus);
initAddBiome(mesaPlateau, Warm, Mesa, 2.0, hHighPlateaus);
// TODO: determine the 1.13 biome properties
initAddBiome(skyIslandLow, Lush, Sky, 0, 0);
initAddBiome(skyIslandMedium, Lush, Sky, 0, 0);
initAddBiome(skyIslandHigh, Lush, Sky, 0, 0);
initAddBiome(skyIslandBarren, Lush, Sky, 0, 0);
initAddBiome(warmOcean, Oceanic, Ocean, 0, 0);
initAddBiome(lukewarmOcean, Oceanic, Ocean, 0, 0);
initAddBiome(coldOcean, Oceanic, Ocean, 0, 0);
initAddBiome(warmDeepOcean, Oceanic, Ocean, 0, 0);
initAddBiome(lukewarmDeepOcean, Oceanic, Ocean, 0, 0);
initAddBiome(coldDeepOcean, Oceanic, Ocean, 0, 0);
initAddBiome(frozenDeepOcean, Oceanic, Ocean, 0, 0);
createMutation(plains);
createMutation(desert);
createMutation(extremeHills);
@ -96,9 +109,11 @@ void initBiomes()
void setWorldSeed(Layer *layer, long seed)
{
if(layer->getMap == mapRiverMix) setWorldSeed(layer->p2, seed);
if(layer->p2 != NULL && layer->getMap != mapHills)
setWorldSeed(layer->p2, seed);
if(layer->p != NULL) setWorldSeed(layer->p, seed);
if(layer->p != NULL)
setWorldSeed(layer->p, seed);
layer->worldSeed = seed;
layer->worldSeed *= layer->worldSeed * 6364136223846793005L + 1442695040888963407L;
@ -291,15 +306,15 @@ void mapAddSnow(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWi
{
int v11 = out[x+1 + (z+1)*pWidth];
if(v11 == 0)
if(isShallowOcean(v11))
{
out[x + z*areaWidth] = 0;
out[x + z*areaWidth] = v11;
}
else
{
setChunkSeed(l, (long)(x + areaX), (long)(z + areaZ));
int r = mcNextInt(l, 6);
char v;
int v;
if(r == 0) v = 4;
else if(r <= 1) v = 3;
@ -312,6 +327,8 @@ void mapAddSnow(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWi
}
void mapCoolWarm(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
int pX = areaX - 1;
@ -454,18 +471,34 @@ void mapDeepOcean(Layer *l, int * __restrict out, int areaX, int areaZ, int area
for(x = 0; x < areaWidth; x++)
{
int v11 = out[(x+1) + (z+1)*pWidth];
int oceans = 0;
// count adjacent oceans
if(out[(x+1) + (z+0)*pWidth] == 0) oceans++;
if(out[(x+2) + (z+1)*pWidth] == 0) oceans++;
if(out[(x+0) + (z+1)*pWidth] == 0) oceans++;
if(out[(x+1) + (z+2)*pWidth] == 0) oceans++;
if(isShallowOcean(v11))
{
// count adjacent oceans
int oceans = 0;
if(isShallowOcean(out[(x+1) + (z+0)*pWidth])) oceans++;
if(isShallowOcean(out[(x+2) + (z+1)*pWidth])) oceans++;
if(isShallowOcean(out[(x+0) + (z+1)*pWidth])) oceans++;
if(isShallowOcean(out[(x+1) + (z+2)*pWidth])) oceans++;
if(v11 == 0 && oceans > 3)
out[x + z*areaWidth] = deepOcean;
else
out[x + z*areaWidth] = v11;
if(oceans > 3)
{
if(v11 == warmOcean)
v11 = warmDeepOcean;
else if(v11 == lukewarmOcean)
v11 = lukewarmDeepOcean;
else if(v11 == ocean)
v11 = deepOcean;
else if(v11 == coldOcean)
v11 = coldDeepOcean;
else if(v11 == frozenOcean)
v11 = frozenDeepOcean;
else
v11 = deepOcean;
}
}
out[x + z*areaWidth] = v11;
}
}
}
@ -855,13 +888,10 @@ void mapRareBiome(Layer *l, int * __restrict out, int areaX, int areaZ, int area
setChunkSeed(l, (long)(x + areaX), (long)(z + areaZ));
int v11 = out[x+1 + (z+1)*pWidth];
if(mcNextInt(l, 57) == 0)
if(mcNextInt(l, 57) == 0 && v11 == plains)
{
// Flower Forest
if(v11 == plains)
out[x + z*areaWidth] = plains + 128;
else
out[x + z*areaWidth] = v11;
out[x + z*areaWidth] = plains + 128;
}
else
{
@ -987,6 +1017,139 @@ void mapRiverMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaW
exit(1);
}
l->p->getMap(l->p, out, areaX, areaZ, areaWidth, areaHeight); // biome chain
memcpy(buf, out, areaWidth*areaHeight*sizeof(int));
l->p2->getMap(l->p2, out, areaX, areaZ, areaWidth, areaHeight); // rivers
for(idx = 0; idx < areaHeight*areaWidth; idx++)
{
if(isOceanic(buf[idx]))
{
out[idx] = buf[idx];
}
else
{
if(out[idx] == river)
{
if(buf[idx] == icePlains)
out[idx] = frozenRiver;
else if(buf[idx] == mushroomIsland || buf[idx] == mushroomIslandShore)
out[idx] = mushroomIslandShore;
else
out[idx] = out[idx] & 255;
}
else
{
out[idx] = buf[idx];
}
}
}
free(buf);
}
void mapOceanTemp(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
// The new ocean branch doesn't actually depend on previous layers.
//int pX = areaX - 1;
//int pZ = areaZ - 1;
//int pWidth = areaWidth + 2;
//int pHeight = areaHeight + 2;
int x, z;
//l->p->getMap(l->p, out, pX, pZ, pWidth, pHeight);
for(z = 0; z < areaHeight; z++)
{
for(x = 0; x < areaWidth; x++)
{
setChunkSeed(l, (long)(x + areaX), (long)(z + areaZ));
int v11;
float tmp = (float)mcNextInt(l, 100) / 100.0f;
if(tmp < 0.05f)
v11 = warmOcean;
else if(tmp < 0.4f)
v11 = lukewarmOcean;
else if(tmp < 0.675f)
v11 = ocean;
else if(tmp < 0.95f)
v11 = coldOcean;
else if(tmp < 1.0f)
v11 = frozenOcean;
else
v11 = ocean;
out[x + z*areaWidth] = v11;
}
}
}
void mapEdgeOcean(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
int pX = areaX - 1;
int pZ = areaZ - 1;
int pWidth = areaWidth + 2;
int pHeight = areaHeight + 2;
int x, z;
l->p->getMap(l->p, out, pX, pZ, pWidth, pHeight);
for(z = 0; z < areaHeight; z++)
{
for(x = 0; x < areaWidth; x++)
{
int v11 = out[x+1 + (z+1)*pWidth];
if(v11 == warmOcean)
{
int v10 = out[x+1 + (z+0)*pWidth];
int v21 = out[x+2 + (z+1)*pWidth];
int v01 = out[x+0 + (z+1)*pWidth];
int v12 = out[x+1 + (z+2)*pWidth];
if(v10 == frozenOcean || v21 == frozenOcean || v01 == frozenOcean || v12 == frozenOcean)
{
v11 = ocean;
}
}
if(v11 == frozenOcean)
{
int v10 = out[x+1 + (z+0)*pWidth];
int v21 = out[x+2 + (z+1)*pWidth];
int v01 = out[x+0 + (z+1)*pWidth];
int v12 = out[x+1 + (z+2)*pWidth];
if(v10 == warmOcean || v21 == warmOcean || v01 == warmOcean || v12 == warmOcean)
{
v11 = ocean;
}
}
out[x + z*areaWidth] = v11;
}
}
}
void mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
int idx;
int *buf = (int*)malloc(areaWidth*areaHeight*sizeof(int));
if(l->p2 == NULL)
{
printf("mapOceanMix() requires two parents! Use setupMultiLayer()\n");
exit(1);
}
l->p->getMap(l->p, out, areaX, areaZ, areaWidth, areaHeight);
memcpy(buf, out, areaWidth*areaHeight*sizeof(int));
@ -994,32 +1157,30 @@ void mapRiverMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaW
for(idx = 0; idx < areaHeight*areaWidth; idx++)
{
if(buf[idx] != ocean && buf[idx] != deepOcean)
{
if (out[idx] == river)
{
if(buf[idx] == icePlains)
out[idx] = frozenRiver;
else if(buf[idx] != mushroomIsland && buf[idx] != mushroomIslandShore)
out[idx] = out[idx] & 255;
else
out[idx] = mushroomIslandShore;
}
else
{
out[idx] = buf[idx];
}
}
else
if(!isOceanic(buf[idx]) || !isOceanic(out[idx]))
{
out[idx] = buf[idx];
}
else if(buf[idx] == deepOcean)
{
if(out[idx] == lukewarmOcean)
out[idx] = lukewarmDeepOcean;
else if(out[idx] == ocean)
out[idx] = deepOcean;
else if(out[idx] == coldOcean)
out[idx] = coldDeepOcean;
else if(out[idx] == frozenOcean)
out[idx] = frozenDeepOcean;
}
}
free(buf);
}
void mapVoronoiZoom(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight)
{
areaX -= 2;

View File

@ -7,12 +7,16 @@
#define OPT_O2 __attribute__((optimize("O2")))
enum BiomeID {
none = -1,
ocean = 0, plains, desert, extremeHills, forest, taiga, swampland, river, hell, sky, // 0-9
frozenOcean, frozenRiver, icePlains, iceMountains, mushroomIsland, mushroomIslandShore, beach, desertHills, forestHills, taigaHills, // 10-19
extremeHillsEdge, jungle, jungleHills, jungleEdge, deepOcean, stoneBeach, coldBeach, birchForest, birchForestHills, roofedForest, // 20-29
coldTaiga, coldTaigaHills, megaTaiga, megaTaigaHills, extremeHillsPlus, savanna, savannaPlateau, mesa, mesaPlateau_F, mesaPlateau, // 30-39
// 1.13
skyIslandLow, skyIslandMedium, skyIslandHigh, skyIslandBarren, warmOcean, lukewarmOcean, coldOcean, warmDeepOcean, lukewarmDeepOcean, coldDeepOcean, // 40-49
frozenDeepOcean,
BIOME_NUM
};
@ -91,11 +95,33 @@ static inline int canBeNeighbors(int id1, int id2)
return tempCat1 == tempCat2;
}
static inline int isShallowOcean(int id)
{
return id == ocean || id == frozenOcean ||
id == warmOcean || id == lukewarmOcean || id == coldOcean;
}
static inline int isOceanic(int id)
{
return id == ocean || id == deepOcean || id == frozenOcean;
switch(id)
{
case ocean:
case deepOcean:
case warmOcean:
case warmDeepOcean:
case lukewarmOcean:
case lukewarmDeepOcean:
case coldOcean:
case coldDeepOcean:
case frozenOcean:
case frozenDeepOcean:
return 1;
default:
return 0;
}
}
static inline int isBiomeSnowy(int id)
{
return biomeExists(id) && biomes[id&0xff].temp < 0.1;
@ -195,7 +221,11 @@ void mapSmooth(Layer *l, int * __restrict out, int x, int z, int w, int h);
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 mapRiverMix(Layer *l, int * __restrict out, int x, int z, int w, int h);
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 mapOceanMix(Layer *l, int * __restrict out, int areaX, int areaZ, int areaWidth, int areaHeight);
void mapVoronoiZoom(Layer *l, int * __restrict out, int x, int z, int w, int h);
#endif /* LAYER_H_ */

View File

@ -63,6 +63,14 @@ void initBiomeColours(unsigned char biomeColours[256][3])
setBiomeColour(biomeColours, mesaPlateau_F, 176, 151, 101);
setBiomeColour(biomeColours, mesaPlateau, 202, 140, 101);
setBiomeColour(biomeColours, warmOcean, 0, 50, 92);
setBiomeColour(biomeColours, lukewarmOcean, 0, 30, 100);
setBiomeColour(biomeColours, coldOcean, 20, 20, 80);
setBiomeColour(biomeColours, warmDeepOcean, 0, 24, 38);
setBiomeColour(biomeColours, lukewarmDeepOcean, 0, 16, 42);
setBiomeColour(biomeColours, coldDeepOcean, 16, 16, 40);
setBiomeColour(biomeColours, frozenDeepOcean, 100, 100, 112);
setBiomeColour(biomeColours, ocean+128, 0, 0, 112);
setBiomeColour(biomeColours, plains+128, 141, 179, 96);