2018-03-06 05:20:54 +08:00
|
|
|
#include "generator.h"
|
|
|
|
#include "layers.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
2020-07-24 04:42:38 +08:00
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2021-01-07 22:03:23 +08:00
|
|
|
l->layerSeed = s ? getLayerSeed(s) : 0;
|
2020-07-24 04:42:38 +08:00
|
|
|
l->startSalt = 0;
|
|
|
|
l->startSeed = 0;
|
2018-03-06 05:20:54 +08:00
|
|
|
l->p = p;
|
|
|
|
l->p2 = NULL;
|
2020-07-24 04:42:38 +08:00
|
|
|
l->scale = 0;
|
2020-08-10 00:52:58 +08:00
|
|
|
l->edge = 0;
|
2018-03-06 05:20:54 +08:00
|
|
|
l->getMap = getMap;
|
2021-01-26 03:01:37 +08:00
|
|
|
l->noise = NULL;
|
2020-08-10 00:52:58 +08:00
|
|
|
l->data = NULL;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
void setupMultiLayer(Layer *l, Layer *p1, Layer *p2, int s, mapfunc_t getMap)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2020-07-24 04:42:38 +08:00
|
|
|
setupLayer(l, p1, s, getMap);
|
2018-03-06 05:20:54 +08:00
|
|
|
l->p2 = p2;
|
|
|
|
}
|
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
static void setupScale(Layer *l, int scale)
|
|
|
|
{
|
|
|
|
l->scale = scale;
|
|
|
|
int m = 1;
|
2020-08-10 00:52:58 +08:00
|
|
|
int e = 0;
|
|
|
|
|
|
|
|
mapfunc_t map = l->getMap;
|
|
|
|
|
2020-10-03 03:58:19 +08:00
|
|
|
if (map == mapZoom || map == mapZoomIsland)
|
2020-08-10 00:52:58 +08:00
|
|
|
{
|
2020-05-05 18:13:43 +08:00
|
|
|
m = 2;
|
2020-10-03 03:58:19 +08:00
|
|
|
e = 3;
|
2020-08-10 00:52:58 +08:00
|
|
|
}
|
|
|
|
else if (map == mapVoronoiZoom)
|
|
|
|
{
|
2020-05-05 18:13:43 +08:00
|
|
|
m = 4;
|
2020-10-03 03:58:19 +08:00
|
|
|
e = 7;
|
2020-08-10 00:52:58 +08:00
|
|
|
}
|
|
|
|
else if (map == mapOceanMix)
|
|
|
|
{
|
|
|
|
e = 17;
|
|
|
|
}
|
|
|
|
else if (
|
|
|
|
map == mapAddIsland ||
|
|
|
|
map == mapRemoveTooMuchOcean ||
|
|
|
|
map == mapAddSnow ||
|
|
|
|
map == mapCoolWarm ||
|
|
|
|
map == mapHeatIce ||
|
|
|
|
map == mapAddMushroomIsland ||
|
|
|
|
map == mapDeepOcean ||
|
|
|
|
map == mapBiomeEdge ||
|
|
|
|
map == mapHills ||
|
2021-01-06 23:23:26 +08:00
|
|
|
map == mapHills112 ||
|
2020-08-10 00:52:58 +08:00
|
|
|
map == mapRiver ||
|
|
|
|
map == mapSmooth ||
|
|
|
|
map == mapShore
|
|
|
|
)
|
|
|
|
{
|
|
|
|
e = 2;
|
2020-05-05 18:13:43 +08:00
|
|
|
}
|
2020-08-10 00:52:58 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
e = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
l->edge = e;
|
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
if (l->p) {
|
|
|
|
setupScale(l->p, scale * m);
|
|
|
|
}
|
|
|
|
if (l->p2) {
|
|
|
|
setupScale(l->p2, scale * m);
|
|
|
|
}
|
|
|
|
}
|
2018-03-18 00:53:16 +08:00
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-07-28 22:36:41 +08:00
|
|
|
if (biomes[plains].id == 0)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
|
|
|
fprintf(stderr, "Warning: The biomes have to be initialised first using initBiomes() before any generator can be used.\n");
|
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
memset(g, 0, sizeof(LayerStack));
|
|
|
|
Layer *l = g->layers;
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-07-24 04:42:38 +08:00
|
|
|
// LAYER PARENT SALT LAYER_FUNCTION
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_ISLAND_4096], NULL, 1, mapIsland);
|
2020-08-10 00:52:58 +08:00
|
|
|
setupLayer(&l[L_ZOOM_2048], &l[L_ISLAND_4096], 2000, mapZoomIsland);
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_ADD_ISLAND_2048], &l[L_ZOOM_2048], 1, mapAddIsland);
|
|
|
|
setupLayer(&l[L_ZOOM_1024], &l[L_ADD_ISLAND_2048], 2001, mapZoom);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_1024A], &l[L_ZOOM_1024], 2, mapAddIsland);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_1024B], &l[L_ADD_ISLAND_1024A], 50, mapAddIsland);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_1024C], &l[L_ADD_ISLAND_1024B], 70, mapAddIsland);
|
|
|
|
setupLayer(&l[L_REMOVE_OCEAN_1024], &l[L_ADD_ISLAND_1024C], 2, mapRemoveTooMuchOcean);
|
|
|
|
|
|
|
|
setupLayer(&l[L_ADD_SNOW_1024], &l[L_REMOVE_OCEAN_1024], 2, mapAddSnow);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_1024D], &l[L_ADD_SNOW_1024], 3, mapAddIsland);
|
|
|
|
setupLayer(&l[L_COOL_WARM_1024], &l[L_ADD_ISLAND_1024D], 2, mapCoolWarm);
|
|
|
|
setupLayer(&l[L_HEAT_ICE_1024], &l[L_COOL_WARM_1024], 2, mapHeatIce);
|
|
|
|
setupLayer(&l[L_SPECIAL_1024], &l[L_HEAT_ICE_1024], 3, mapSpecial);
|
|
|
|
setupLayer(&l[L_ZOOM_512], &l[L_SPECIAL_1024], 2002, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_256], &l[L_ZOOM_512], 2003, mapZoom);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_256], &l[L_ZOOM_256], 4, mapAddIsland);
|
|
|
|
setupLayer(&l[L_ADD_MUSHROOM_256], &l[L_ADD_ISLAND_256], 5, mapAddMushroomIsland);
|
|
|
|
setupLayer(&l[L_DEEP_OCEAN_256], &l[L_ADD_MUSHROOM_256], 4, mapDeepOcean);
|
2018-03-06 05:20:54 +08:00
|
|
|
// biome layer chain
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_BIOME_256], &l[L_DEEP_OCEAN_256], 200,
|
2020-07-26 00:16:39 +08:00
|
|
|
mcversion != MC_BE ? mapBiome : mapBiomeBE);
|
2018-03-06 05:20:54 +08:00
|
|
|
|
2019-05-07 05:14:25 +08:00
|
|
|
if (mcversion <= MC_1_13)
|
2020-07-24 04:42:38 +08:00
|
|
|
setupLayer(&l[L_ZOOM_128], &l[L_BIOME_256], 1000, mapZoom);
|
2019-05-07 05:14:25 +08:00
|
|
|
else
|
2018-03-11 05:45:57 +08:00
|
|
|
{
|
2020-07-24 04:42:38 +08:00
|
|
|
setupLayer(&l[L14_BAMBOO_256], &l[L_BIOME_256], 1001, mapAddBamboo);
|
|
|
|
setupLayer(&l[L_ZOOM_128], &l[L14_BAMBOO_256], 1000, mapZoom);
|
2018-03-11 05:45:57 +08:00
|
|
|
}
|
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_ZOOM_64], &l[L_ZOOM_128], 1001, mapZoom);
|
|
|
|
setupLayer(&l[L_BIOME_EDGE_64], &l[L_ZOOM_64], 1000, mapBiomeEdge);
|
2018-03-11 05:45:57 +08:00
|
|
|
|
|
|
|
// basic river layer chain, used to determine where hills generate
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_RIVER_INIT_256], &l[L_DEEP_OCEAN_256], 100, mapRiverInit);
|
2021-01-07 22:03:23 +08:00
|
|
|
setupLayer(&l[L_ZOOM_128_HILLS], &l[L_RIVER_INIT_256], mcversion < MC_1_13 ? 0 : 1000, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_64_HILLS], &l[L_ZOOM_128_HILLS], mcversion < MC_1_13 ? 0 : 1001, mapZoom);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupMultiLayer(&l[L_HILLS_64], &l[L_BIOME_EDGE_64], &l[L_ZOOM_64_HILLS], 1000,
|
2021-01-08 00:17:21 +08:00
|
|
|
mcversion <= MC_1_12 ? mapHills112 : mapHills);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_RARE_BIOME_64], &l[L_HILLS_64], 1001, mapRareBiome);
|
|
|
|
setupLayer(&l[L_ZOOM_32], &l[L_RARE_BIOME_64], 1000, mapZoom);
|
|
|
|
setupLayer(&l[L_ADD_ISLAND_32], &l[L_ZOOM_32], 3, mapAddIsland);
|
|
|
|
setupLayer(&l[L_ZOOM_16], &l[L_ADD_ISLAND_32], 1001, mapZoom);
|
|
|
|
setupLayer(&l[L_SHORE_16], &l[L_ZOOM_16], 1000, mapShore);
|
|
|
|
setupLayer(&l[L_ZOOM_8], &l[L_SHORE_16], 1002, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_4], &l[L_ZOOM_8], 1003, mapZoom);
|
2020-05-05 17:32:35 +08:00
|
|
|
|
2020-05-05 18:49:06 +08:00
|
|
|
if (largeBiomes != 0) {
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_ZOOM_LARGE_BIOME_A], &l[L_ZOOM_4], 1004, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_LARGE_BIOME_B], &l[L_ZOOM_LARGE_BIOME_A], 1005, mapZoom);
|
|
|
|
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_LARGE_BIOME_B], 1000, mapSmooth);
|
2020-05-05 17:32:35 +08:00
|
|
|
} else {
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_SMOOTH_4], &l[L_ZOOM_4], 1000, mapSmooth);
|
2020-05-05 17:32:35 +08:00
|
|
|
}
|
2018-03-11 05:45:57 +08:00
|
|
|
|
|
|
|
// river layer chain
|
2020-05-05 18:13:43 +08:00
|
|
|
setupLayer(&l[L_ZOOM_128_RIVER], &l[L_RIVER_INIT_256], 1000, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_64_RIVER], &l[L_ZOOM_128_RIVER], 1001, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_32_RIVER], &l[L_ZOOM_64_RIVER], 1000, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_16_RIVER], &l[L_ZOOM_32_RIVER], 1001, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_8_RIVER], &l[L_ZOOM_16_RIVER], 1002, mapZoom);
|
|
|
|
setupLayer(&l[L_ZOOM_4_RIVER], &l[L_ZOOM_8_RIVER], 1003, mapZoom);
|
|
|
|
setupLayer(&l[L_RIVER_4], &l[L_ZOOM_4_RIVER], 1, mapRiver);
|
|
|
|
setupLayer(&l[L_SMOOTH_4_RIVER], &l[L_RIVER_4], 1000, mapSmooth);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupMultiLayer(&l[L_RIVER_MIX_4], &l[L_SMOOTH_4], &l[L_SMOOTH_4_RIVER], 100, mapRiverMix);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
|
|
|
if (mcversion <= MC_1_12)
|
2018-11-29 12:32:12 +08:00
|
|
|
{
|
2020-08-10 00:52:58 +08:00
|
|
|
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L_RIVER_MIX_4], 10, mapVoronoiZoom);
|
|
|
|
g->entry_4 = &l[L_RIVER_MIX_4];
|
2019-05-07 05:14:25 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ocean variants
|
2020-08-10 00:52:58 +08:00
|
|
|
setupLayer(&l[L13_OCEAN_TEMP_256], NULL, 2, mapOceanTemp);
|
2021-01-26 03:01:37 +08:00
|
|
|
l[L13_OCEAN_TEMP_256].noise = &g->oceanRnd;
|
2020-08-10 00:52:58 +08:00
|
|
|
setupLayer(&l[L13_ZOOM_128], &l[L13_OCEAN_TEMP_256], 2001, mapZoom);
|
|
|
|
setupLayer(&l[L13_ZOOM_64], &l[L13_ZOOM_128], 2002, mapZoom);
|
|
|
|
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
|
|
|
|
setupLayer(&l[L13_ZOOM_16], &l[L13_ZOOM_32], 2004, mapZoom);
|
|
|
|
setupLayer(&l[L13_ZOOM_8], &l[L13_ZOOM_16], 2005, mapZoom);
|
|
|
|
setupLayer(&l[L13_ZOOM_4], &l[L13_ZOOM_8], 2006, mapZoom);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupMultiLayer(&l[L13_OCEAN_MIX_4], &l[L_RIVER_MIX_4], &l[L13_ZOOM_4], 100, mapOceanMix);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
setupLayer(&l[L_VORONOI_ZOOM_1], &l[L13_OCEAN_MIX_4], 10, mapVoronoiZoom);
|
|
|
|
g->entry_4 = &l[L13_OCEAN_MIX_4];
|
2018-11-29 12:32:12 +08:00
|
|
|
}
|
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
setupScale(&l[L_VORONOI_ZOOM_1], 1);
|
2020-08-10 00:52:58 +08:00
|
|
|
g->entry_1 = &l[L_VORONOI_ZOOM_1];
|
2018-11-29 12:32:12 +08:00
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
void setupGenerator(LayerStack *g, int mcversion)
|
2020-05-05 18:49:06 +08:00
|
|
|
{
|
2020-08-10 00:52:58 +08:00
|
|
|
setupGeneratorImpl(g, mcversion, 0);
|
2020-05-05 18:49:06 +08:00
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
void setupLargeBiomesGenerator(LayerStack *g, int mcversion)
|
2020-05-05 18:49:06 +08:00
|
|
|
{
|
2020-08-10 00:52:58 +08:00
|
|
|
setupGeneratorImpl(g, mcversion, 1);
|
2018-07-28 22:36:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Recursively calculates the minimum buffer size required to generate an area
|
|
|
|
* of the specified size from the current layer onwards.
|
|
|
|
*/
|
2020-07-26 00:16:39 +08:00
|
|
|
static void getMaxArea(const Layer *layer, int areaX, int areaZ, int *maxX, int *maxZ)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-07-28 22:36:41 +08:00
|
|
|
if (layer == NULL)
|
2018-03-11 05:45:57 +08:00
|
|
|
return;
|
2018-03-06 05:20:54 +08:00
|
|
|
|
2020-10-03 03:58:19 +08:00
|
|
|
if (layer->getMap == mapZoom || layer->getMap == mapZoomIsland)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2020-08-10 00:52:58 +08:00
|
|
|
areaX >>= 1;
|
|
|
|
areaZ >>= 1;
|
2018-03-11 05:45:57 +08:00
|
|
|
}
|
2018-07-28 22:36:41 +08:00
|
|
|
else if (layer->getMap == mapVoronoiZoom)
|
2018-03-11 05:45:57 +08:00
|
|
|
{
|
2020-08-10 00:52:58 +08:00
|
|
|
areaX >>= 2;
|
|
|
|
areaZ >>= 2;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
areaX += layer->edge;
|
|
|
|
areaZ += layer->edge;
|
|
|
|
|
2018-07-28 22:36:41 +08:00
|
|
|
if (areaX > *maxX) *maxX = areaX;
|
|
|
|
if (areaZ > *maxZ) *maxZ = areaZ;
|
2018-03-11 05:45:57 +08:00
|
|
|
|
|
|
|
getMaxArea(layer->p, areaX, areaZ, maxX, maxZ);
|
|
|
|
getMaxArea(layer->p2, areaX, areaZ, maxX, maxZ);
|
|
|
|
}
|
|
|
|
|
2020-07-26 00:16:39 +08:00
|
|
|
int calcRequiredBuf(const Layer *layer, int areaX, int areaZ)
|
2018-03-11 05:45:57 +08:00
|
|
|
{
|
|
|
|
int maxX = areaX, maxZ = areaZ;
|
|
|
|
getMaxArea(layer, areaX, areaZ, &maxX, &maxZ);
|
|
|
|
|
|
|
|
return maxX * maxZ;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2020-07-26 00:16:39 +08:00
|
|
|
int *allocCache(const Layer *layer, int sizeX, int sizeZ)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-07-28 22:36:41 +08:00
|
|
|
int size = calcRequiredBuf(layer, sizeX, sizeZ);
|
2018-07-08 22:13:09 +08:00
|
|
|
|
2018-07-28 22:36:41 +08:00
|
|
|
int *ret = (int *) malloc(sizeof(*ret)*size);
|
|
|
|
memset(ret, 0, sizeof(*ret)*size);
|
|
|
|
|
|
|
|
return ret;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2018-07-28 22:36:41 +08:00
|
|
|
|
2018-07-04 23:48:05 +08:00
|
|
|
void applySeed(LayerStack *g, int64_t seed)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2018-03-11 05:45:57 +08:00
|
|
|
// the seed has to be applied recursively
|
2019-05-07 05:14:25 +08:00
|
|
|
setWorldSeed(&g->layers[L_VORONOI_ZOOM_1], seed);
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2020-08-10 00:52:58 +08:00
|
|
|
int genArea(const Layer *layer, int *out, int areaX, int areaZ, int areaWidth, int areaHeight)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
|
|
|
memset(out, 0, areaWidth*areaHeight*sizeof(*out));
|
2020-08-10 00:52:58 +08:00
|
|
|
return layer->getMap(layer, out, areaX, areaZ, areaWidth, areaHeight);
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|