2018-03-06 05:20:54 +08:00
|
|
|
#include "generator.h"
|
|
|
|
#include "layers.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
int *allocCache(Generator *g, int sizeX, int sizeZ)
|
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
int size = calcRequiredBuf(&g->layers[g->topLayerIndex-1], sizeX, sizeZ);
|
|
|
|
|
2018-03-06 05:20:54 +08:00
|
|
|
int *ret = (int*) malloc(sizeof(*ret)*size);
|
|
|
|
memset(ret, 0, sizeof(*ret)*size);
|
2018-03-11 05:45:57 +08:00
|
|
|
|
2018-03-06 05:20:54 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setupLayer(Layer *l, Layer *p, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h))
|
|
|
|
{
|
|
|
|
setBaseSeed(l, s);
|
|
|
|
l->p = p;
|
|
|
|
l->p2 = NULL;
|
|
|
|
l->getMap = getMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, void (*getMap)(Layer *layer, int *out, int x, int z, int w, int h))
|
|
|
|
{
|
|
|
|
setBaseSeed(l, s);
|
|
|
|
l->p = p1;
|
|
|
|
l->p2 = p2;
|
|
|
|
l->getMap = getMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
Generator setupGenerator()
|
2018-03-11 05:45:57 +08:00
|
|
|
{
|
|
|
|
return setupGeneratorMC18();
|
|
|
|
}
|
|
|
|
|
|
|
|
Generator setupGeneratorMC18()
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
|
|
|
if(biomes[plains].id == 0)
|
|
|
|
{
|
|
|
|
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 = 44;
|
|
|
|
g.layerMax = 44;
|
|
|
|
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);
|
|
|
|
setupLayer(&g.layers[43], &g.layers[42], 10, mapVoronoiZoom);
|
|
|
|
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
2018-03-11 05:45:57 +08:00
|
|
|
|
|
|
|
Generator setupGeneratorMC113()
|
|
|
|
{
|
|
|
|
if(biomes[plains].id == 0)
|
|
|
|
{
|
|
|
|
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)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
if(topLevel > g->layerMax)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
printf("Warning: Top layer index is greater than the number of layers in this generator.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g->topLayerIndex = topLevel;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-11 05:45:57 +08:00
|
|
|
|
|
|
|
static void getMaxArea(Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
if(layer == NULL)
|
|
|
|
return;
|
2018-03-06 05:20:54 +08:00
|
|
|
|
2018-03-11 05:45:57 +08:00
|
|
|
if(layer->getMap == mapZoom)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
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 )
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
|
|
|
areaX += 2;
|
|
|
|
areaZ += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-11 05:45:57 +08:00
|
|
|
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;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void freeGenerator(Generator *g)
|
|
|
|
{
|
|
|
|
free(g->layers);
|
|
|
|
}
|
|
|
|
|
|
|
|
void applySeed(Generator *g, long seed)
|
|
|
|
{
|
|
|
|
g->rawSeed = seed;
|
|
|
|
|
2018-03-11 05:45:57 +08:00
|
|
|
// the seed has to be applied recursively
|
2018-03-06 05:20:54 +08:00
|
|
|
setWorldSeed(&g->layers[g->topLayerIndex-1], seed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void genArea(Generator *g, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
|
|
|
{
|
|
|
|
Layer *l = &g->layers[g->topLayerIndex-1];
|
|
|
|
memset(out, 0, areaWidth*areaHeight*sizeof(*out));
|
|
|
|
l->getMap(l, out, areaX, areaZ, areaWidth, areaHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|