mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 03:33:50 -04:00
added 1.13 biome generator
This commit is contained in:
parent
c26e57a1ce
commit
4db50a4e6d
167
finders.c
167
finders.c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
197
generator.c
197
generator.c
@ -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);
|
||||
}
|
||||
|
||||
|
33
generator.h
33
generator.h
@ -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
235
layers.c
@ -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;
|
||||
|
34
layers.h
34
layers.h
@ -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_ */
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user