2018-03-06 05:20:54 +08:00
|
|
|
#include "generator.h"
|
|
|
|
#include "layers.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
Layer *setupLayer(LayerStack *g, int layerId, mapfunc_t *map, int mc,
|
2021-04-19 01:50:08 +08:00
|
|
|
int8_t zoom, int8_t edge, int saltbase, Layer *p, Layer *p2)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2021-04-19 01:50:08 +08:00
|
|
|
Layer *l = g->layers + layerId;
|
|
|
|
l->getMap = map;
|
|
|
|
l->mc = mc;
|
|
|
|
l->zoom = zoom;
|
|
|
|
l->edge = edge;
|
|
|
|
l->scale = 0;
|
|
|
|
l->layerSalt = saltbase > 0 ? getLayerSalt(saltbase) : saltbase;
|
2020-07-24 04:42:38 +08:00
|
|
|
l->startSalt = 0;
|
|
|
|
l->startSeed = 0;
|
2021-01-26 03:01:37 +08:00
|
|
|
l->noise = NULL;
|
2020-08-10 00:52:58 +08:00
|
|
|
l->data = NULL;
|
2021-04-19 01:50:08 +08:00
|
|
|
l->p = p;
|
2018-03-06 05:20:54 +08:00
|
|
|
l->p2 = p2;
|
2021-04-19 01:50:08 +08:00
|
|
|
return l;
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
|
|
|
|
2020-05-05 18:13:43 +08:00
|
|
|
static void setupScale(Layer *l, int scale)
|
|
|
|
{
|
2021-04-21 05:13:53 +08:00
|
|
|
l->scale = scale;
|
2021-04-19 01:50:08 +08:00
|
|
|
if (l->p)
|
|
|
|
setupScale(l->p, scale * l->zoom);
|
|
|
|
if (l->p2)
|
|
|
|
setupScale(l->p2, scale * l->zoom);
|
2020-05-05 18:13:43 +08:00
|
|
|
}
|
2018-03-18 00:53:16 +08:00
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
static void setupGeneratorImpl(LayerStack *g, int mc, int largeBiomes)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2021-04-19 01:50:08 +08:00
|
|
|
memset(g, 0, sizeof(LayerStack));
|
|
|
|
Layer *p;
|
|
|
|
|
|
|
|
// G: generator layer stack
|
|
|
|
// L: layer ID
|
|
|
|
// M: mapping function
|
|
|
|
// V: minecraft version
|
|
|
|
// Z: zoom
|
|
|
|
// E: edge
|
|
|
|
// S: salt base
|
|
|
|
// P1: parent 1
|
|
|
|
// P2: parent 2
|
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
// G, L, M V Z E S P1 P2
|
|
|
|
p = setupLayer(g, L_CONTINENT_4096, mapContinent, mc, 1, 0, 1, 0, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_2048, mapZoomFuzzy, mc, 2, 3, 2000, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_2048, mapLand, mc, 1, 2, 1, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_1024, mapZoom, mc, 2, 3, 2001, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_1024_A, mapLand, mc, 1, 2, 2, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
|
|
|
if (mc <= MC_1_6)
|
2018-03-06 05:20:54 +08:00
|
|
|
{
|
2021-04-21 05:13:53 +08:00
|
|
|
// G L M V Z E S P1 P2
|
|
|
|
p = setupLayer(g, L_SNOW_1024, mapSnow16, mc, 1, 2, 2, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_512, mapZoom, mc, 2, 3, 2002, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_512, mapLand16, mc, 1, 2, 3, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_256, mapZoom, mc, 2, 3, 2003, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_256, mapLand16, mc, 1, 2, 4, p, 0);
|
|
|
|
p = setupLayer(g, L_MUSHROOM_256, mapMushroom, mc, 1, 2, 5, p, 0);
|
|
|
|
p = setupLayer(g, L_BIOME_256, mapBiome, mc, 1, 0, 200, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_128, mapZoom, mc, 2, 3, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
|
|
|
|
// river noise layer chain, also used to determine where hills generate
|
|
|
|
p = setupLayer(g, L_NOISE_256, mapNoise, mc, 1, 0, 100,
|
|
|
|
g->layers+L_MUSHROOM_256, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_128_HILLS, mapZoom, mc, 2, 3, 0, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64_HILLS, mapZoom, mc, 2, 3, 0, p, 0);
|
|
|
|
|
|
|
|
p = setupLayer(g, L_HILLS_64, mapHills, mc, 1, 2, 1000,
|
2021-04-19 01:50:08 +08:00
|
|
|
g->layers+L_ZOOM_64, g->layers+L_ZOOM_64_HILLS);
|
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_ZOOM_32, mapZoom, mc, 2, 3, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_32, mapLand16, mc, 1, 2, 3, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_16, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_SHORE_16, mapShore, mc, 1, 2, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_SWAMP_RIVER_16, mapSwampRiver, mc, 1, 0, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_8, mapZoom, mc, 2, 3, 1002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_4, mapZoom, mc, 2, 3, 1003, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_SMOOTH_4, mapSmooth, mc, 1, 2, 1000, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
|
|
|
// river layer chain
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_ZOOM_128_RIVER, mapZoom, mc, 2, 3, 1000,
|
|
|
|
g->layers+L_NOISE_256, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64_RIVER, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_32_RIVER, mapZoom, mc, 2, 3, 1002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_16_RIVER, mapZoom, mc, 2, 3, 1003, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_8_RIVER, mapZoom, mc, 2, 3, 1004, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_4_RIVER, mapZoom, mc, 2, 3, 1005, p, 0);
|
|
|
|
p = setupLayer(g, L_RIVER_4, mapRiver, mc, 1, 2, 1, p, 0);
|
|
|
|
p = setupLayer(g, L_SMOOTH_4_RIVER, mapSmooth, mc, 1, 2, 1000, p, 0);
|
2018-03-06 05:20:54 +08:00
|
|
|
}
|
2019-05-07 05:14:25 +08:00
|
|
|
else
|
2018-03-11 05:45:57 +08:00
|
|
|
{
|
2021-04-21 05:13:53 +08:00
|
|
|
// G L M V Z E S P1 P2
|
|
|
|
p = setupLayer(g, L_LAND_1024_B, mapLand, mc, 1, 2, 50, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_1024_C, mapLand, mc, 1, 2, 70, p, 0);
|
|
|
|
p = setupLayer(g, L_ISLAND_1024, mapIsland, mc, 1, 2, 2, p, 0);
|
|
|
|
p = setupLayer(g, L_SNOW_1024, mapSnow, mc, 1, 2, 2, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_1024_D, mapLand, mc, 1, 2, 3, p, 0);
|
|
|
|
p = setupLayer(g, L_COOL_1024, mapCool, mc, 1, 2, 2, p, 0);
|
|
|
|
p = setupLayer(g, L_HEAT_1024, mapHeat, mc, 1, 2, 2, p, 0);
|
|
|
|
p = setupLayer(g, L_SPECIAL_1024, mapSpecial, mc, 1, 2, 3, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_512, mapZoom, mc, 2, 3, 2002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_256, mapZoom, mc, 2, 3, 2003, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_256, mapLand, mc, 1, 2, 4, p, 0);
|
|
|
|
p = setupLayer(g, L_MUSHROOM_256, mapMushroom, mc, 1, 2, 5, p, 0);
|
|
|
|
p = setupLayer(g, L_DEEP_OCEAN_256, mapDeepOcean, mc, 1, 2, 4, p, 0);
|
|
|
|
p = setupLayer(g, L_BIOME_256, mapBiome, mc, 1, 0, 200, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
if (mc > MC_1_13)
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_BAMBOO_256, mapBamboo, mc, 1, 0, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_128, mapZoom, mc, 2, 3, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_BIOME_EDGE_64, mapBiomeEdge, mc, 1, 2, 1000, p, 0);
|
|
|
|
|
|
|
|
// river noise layer chain, also used to determine where hills generate
|
|
|
|
p = setupLayer(g, L_RIVER_INIT_256, mapNoise, mc, 1, 0, 100,
|
|
|
|
g->layers+L_DEEP_OCEAN_256, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_128_HILLS, mapZoom, mc, 2, 3, mc < MC_1_13 ? 0 : 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64_HILLS, mapZoom, mc, 2, 3, mc < MC_1_13 ? 0 : 1001, p, 0);
|
|
|
|
|
|
|
|
p = setupLayer(g, L_HILLS_64, mapHills, mc, 1, 2, 1000,
|
2021-04-19 01:50:08 +08:00
|
|
|
g->layers+L_BIOME_EDGE_64, g->layers+L_ZOOM_64_HILLS);
|
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_SUNFLOWER_64, mapSunflower, mc, 1, 0, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_32, mapZoom, mc, 2, 3, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_LAND_32, mapLand, mc, 1, 2, 3, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_16, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_SHORE_16, mapShore, mc, 1, 2, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_8, mapZoom, mc, 2, 3, 1002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_4, mapZoom, mc, 2, 3, 1003, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
|
|
|
if (largeBiomes)
|
|
|
|
{
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_ZOOM_LARGE_BIOME_A, mapZoom, mc, 2, 3, 1004, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_LARGE_BIOME_B, mapZoom, mc, 2, 3, 1005, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
}
|
|
|
|
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_SMOOTH_4, mapSmooth, mc, 1, 2, 1000, p, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
|
|
|
// river layer chain
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_ZOOM_128_RIVER, mapZoom, mc, 2, 3, 1000,
|
|
|
|
g->layers+L_RIVER_INIT_256, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64_RIVER, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_32_RIVER, mapZoom, mc, 2, 3, 1000, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_16_RIVER, mapZoom, mc, 2, 3, 1001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_8_RIVER, mapZoom, mc, 2, 3, 1002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_4_RIVER, mapZoom, mc, 2, 3, 1003, p, 0);
|
|
|
|
p = setupLayer(g, L_RIVER_4, mapRiver, mc, 1, 2, 1, p, 0);
|
|
|
|
p = setupLayer(g, L_SMOOTH_4_RIVER, mapSmooth, mc, 1, 2, 1000, p, 0);
|
2020-05-05 17:32:35 +08:00
|
|
|
}
|
2018-03-11 05:45:57 +08:00
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
p = setupLayer(g, L_RIVER_MIX_4, mapRiverMix, mc, 1, 0, 100,
|
|
|
|
g->layers+L_SMOOTH_4, g->layers+L_SMOOTH_4_RIVER);
|
2019-05-07 05:14:25 +08:00
|
|
|
|
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
if (mc <= MC_1_12)
|
2018-11-29 12:32:12 +08:00
|
|
|
{
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_VORONOI_1, mapVoronoi114, mc, 4, 7, 10, p, 0);
|
2019-05-07 05:14:25 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ocean variants
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_OCEAN_TEMP_256, mapOceanTemp, mc, 1, 0, 2, 0, 0);
|
2021-04-19 01:50:08 +08:00
|
|
|
p->noise = &g->oceanRnd;
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_ZOOM_128_OCEAN, mapZoom, mc, 2, 3, 2001, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_64_OCEAN, mapZoom, mc, 2, 3, 2002, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_32_OCEAN, mapZoom, mc, 2, 3, 2003, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_16_OCEAN, mapZoom, mc, 2, 3, 2004, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_8_OCEAN, mapZoom, mc, 2, 3, 2005, p, 0);
|
|
|
|
p = setupLayer(g, L_ZOOM_4_OCEAN, mapZoom, mc, 2, 3, 2006, p, 0);
|
|
|
|
p = setupLayer(g, L_OCEAN_MIX_4, mapOceanMix, mc, 1, 17, 100,
|
|
|
|
g->layers+L_RIVER_MIX_4, g->layers+L_ZOOM_4_OCEAN);
|
2021-04-19 01:50:08 +08:00
|
|
|
|
|
|
|
if (mc <= MC_1_14)
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_VORONOI_1, mapVoronoi114, mc, 4, 7, 10, p, 0);
|
2021-03-06 23:20:24 +08:00
|
|
|
else
|
2021-04-21 05:13:53 +08:00
|
|
|
p = setupLayer(g, L_VORONOI_1, mapVoronoi, mc, 4, 7, -1, p, 0);
|
2018-11-29 12:32:12 +08:00
|
|
|
}
|
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
g->entry_1 = p;
|
2021-04-21 05:13:53 +08:00
|
|
|
g->entry_4 = g->layers + (mc <= MC_1_12 ? L_RIVER_MIX_4 : L_OCEAN_MIX_4);
|
2021-04-27 00:26:15 +08:00
|
|
|
g->entry_16 = g->layers + (mc <= MC_1_6 ? L_SWAMP_RIVER_16 : L_SHORE_16);
|
|
|
|
g->entry_64 = g->layers + (mc <= MC_1_7 ? L_HILLS_64 : L_SUNFLOWER_64);
|
|
|
|
g->entry_256 = g->layers + (mc <= MC_1_14 ? L_BIOME_256 : L_BAMBOO_256);
|
2021-04-19 01:50:08 +08:00
|
|
|
setupScale(g->entry_1, 1);
|
2018-11-29 12:32:12 +08:00
|
|
|
}
|
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
void setupGenerator(LayerStack *g, int mc)
|
2020-05-05 18:49:06 +08:00
|
|
|
{
|
2021-04-19 01:50:08 +08:00
|
|
|
setupGeneratorImpl(g, mc, 0);
|
2020-05-05 18:49:06 +08:00
|
|
|
}
|
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
void setupLargeBiomesGenerator(LayerStack *g, int mc)
|
2020-05-05 18:49:06 +08:00
|
|
|
{
|
2021-04-19 01:50:08 +08:00
|
|
|
setupGeneratorImpl(g, mc, 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
|
|
|
|
2021-04-19 01:50:08 +08:00
|
|
|
if (layer->zoom == 2)
|
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
|
|
|
}
|
2021-04-19 01:50:08 +08:00
|
|
|
else if (layer->zoom == 4)
|
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
|
2021-03-06 23:20:24 +08:00
|
|
|
setLayerSeed(g->entry_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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|