mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-08-03 09:46:41 -04:00
some fixes + 1.20 snapshot
* added 1.20 biome generation * added nptree scripts to docu * fixed stronghold biomes for pre-1.13 (#92) * fixed wrong ID for non-generating biome in 1.9 - 1.10 (MC-98995) * fixed incorrect buffer requirements for non-overworld voronoi * slightly improved accuracy of scaled biomes for beta 1.7 * renamed enums for spline noise parameters (#95) * removed redundant enum for 1.19.3 for now (use MC_1_19 instead)
This commit is contained in:
parent
1585006467
commit
119f3e7d76
2450
biome_tree.c
2450
biome_tree.c
File diff suppressed because it is too large
Load Diff
193
docs/nptree_bin.py
Normal file
193
docs/nptree_bin.py
Normal file
@ -0,0 +1,193 @@
|
||||
import sys
|
||||
import re
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
msg = \
|
||||
"""
|
||||
usage: {0} FILE
|
||||
Compresses the C biome tree into a 64-bit binary table where the bytes
|
||||
index the noise points in a secondary table. Biomes are converted to their
|
||||
numeric ID and are also stored inside the binary table.
|
||||
""".format(sys.argv[0])
|
||||
print(msg)
|
||||
sys.exit(0)
|
||||
|
||||
in_file = sys.argv[1]
|
||||
|
||||
|
||||
bdic = dict()
|
||||
|
||||
auto_cnt = 0
|
||||
def auto(n=None):
|
||||
global auto_cnt
|
||||
if n is not None:
|
||||
auto_cnt = n
|
||||
ret = auto_cnt
|
||||
auto_cnt += 1
|
||||
return ret
|
||||
|
||||
bdic['ocean'] = auto(0)
|
||||
bdic['plains'] = auto()
|
||||
bdic['desert'] = auto()
|
||||
bdic['mountains'] = auto()
|
||||
bdic['forest'] = auto()
|
||||
bdic['taiga'] = auto()
|
||||
bdic['swamp'] = auto()
|
||||
bdic['river'] = auto()
|
||||
bdic['nether_wastes'] = auto()
|
||||
bdic['the_end'] = auto()
|
||||
# // 10
|
||||
bdic['frozen_ocean'] = auto()
|
||||
bdic['frozen_river'] = auto()
|
||||
bdic['snowy_tundra'] = auto()
|
||||
bdic['snowy_mountains'] = auto()
|
||||
bdic['mushroom_fields'] = auto()
|
||||
bdic['mushroom_field_shore'] = auto()
|
||||
bdic['beach'] = auto()
|
||||
bdic['desert_hills'] = auto()
|
||||
bdic['wooded_hills'] = auto()
|
||||
bdic['taiga_hills'] = auto()
|
||||
# // 20
|
||||
bdic['mountain_edge'] = auto()
|
||||
bdic['jungle'] = auto()
|
||||
bdic['jungle_hills'] = auto()
|
||||
bdic['jungle_edge'] = auto()
|
||||
bdic['deep_ocean'] = auto()
|
||||
bdic['stone_shore'] = auto()
|
||||
bdic['snowy_beach'] = auto()
|
||||
bdic['birch_forest'] = auto()
|
||||
bdic['birch_forest_hills'] = auto()
|
||||
bdic['dark_forest'] = auto()
|
||||
# // 30
|
||||
bdic['snowy_taiga'] = auto()
|
||||
bdic['snowy_taiga_hills'] = auto()
|
||||
bdic['giant_tree_taiga'] = auto()
|
||||
bdic['giant_tree_taiga_hills'] = auto()
|
||||
bdic['wooded_mountains'] = auto()
|
||||
bdic['savanna'] = auto()
|
||||
bdic['savanna_plateau'] = auto()
|
||||
bdic['badlands'] = auto()
|
||||
bdic['wooded_badlands_plateau'] = auto()
|
||||
bdic['badlands_plateau'] = auto()
|
||||
# // 40 -- 1.13
|
||||
bdic['small_end_islands'] = auto()
|
||||
bdic['end_midlands'] = auto()
|
||||
bdic['end_highlands'] = auto()
|
||||
bdic['end_barrens'] = auto()
|
||||
bdic['warm_ocean'] = auto()
|
||||
bdic['lukewarm_ocean'] = auto()
|
||||
bdic['cold_ocean'] = auto()
|
||||
bdic['deep_warm_ocean'] = auto()
|
||||
bdic['deep_lukewarm_ocean'] = auto()
|
||||
bdic['deep_cold_ocean'] = auto()
|
||||
# // 50
|
||||
bdic['deep_frozen_ocean'] = auto()
|
||||
|
||||
bdic['the_void'] = auto(127)
|
||||
|
||||
bdic['sunflower_plains'] = bdic['plains']+128
|
||||
bdic['desert_lakes'] = bdic['desert']+128
|
||||
bdic['gravelly_mountains'] = bdic['mountains']+128
|
||||
bdic['flower_forest'] = bdic['forest']+128
|
||||
bdic['taiga_mountains'] = bdic['taiga']+128
|
||||
bdic['swamp_hills'] = bdic['swamp']+128
|
||||
bdic['ice_spikes'] = bdic['snowy_tundra']+128
|
||||
bdic['modified_jungle'] = bdic['jungle']+128
|
||||
bdic['modified_jungle_edge'] = bdic['jungle_edge']+128
|
||||
bdic['tall_birch_forest'] = bdic['birch_forest']+128
|
||||
bdic['tall_birch_hills'] = bdic['birch_forest_hills']+128
|
||||
bdic['dark_forest_hills'] = bdic['dark_forest']+128
|
||||
bdic['snowy_taiga_mountains'] = bdic['snowy_taiga']+128
|
||||
bdic['giant_spruce_taiga'] = bdic['giant_tree_taiga']+128
|
||||
bdic['giant_spruce_taiga_hills'] = bdic['giant_tree_taiga_hills']+128
|
||||
bdic['modified_gravelly_mountains'] = bdic['wooded_mountains']+128
|
||||
bdic['shattered_savanna'] = bdic['savanna']+128
|
||||
bdic['shattered_savanna_plateau'] = bdic['savanna_plateau']+128
|
||||
bdic['eroded_badlands'] = bdic['badlands']+128
|
||||
bdic['modified_wooded_badlands_plateau'] = bdic['wooded_badlands_plateau']+128
|
||||
bdic['modified_badlands_plateau'] = bdic['badlands_plateau']+128
|
||||
# // 1.14
|
||||
bdic['bamboo_jungle'] = 168
|
||||
bdic['bamboo_jungle_hills'] = 169
|
||||
# // 1.16
|
||||
bdic['soul_sand_valley'] = 170
|
||||
bdic['crimson_forest'] = 171
|
||||
bdic['warped_forest'] = 172
|
||||
bdic['basalt_deltas'] = 173
|
||||
# // 1.17
|
||||
bdic['dripstone_caves'] = 174
|
||||
bdic['lush_caves'] = 175
|
||||
# // 1.18
|
||||
bdic['meadow'] = 177
|
||||
bdic['grove'] = 178
|
||||
bdic['snowy_slopes'] = 179
|
||||
bdic['jagged_peaks'] = 180
|
||||
bdic['frozen_peaks'] = 181
|
||||
bdic['stony_peaks'] = 182
|
||||
bdic['old_growth_birch_forest'] = bdic['tall_birch_forest']
|
||||
bdic['old_growth_pine_taiga'] = bdic['giant_tree_taiga']
|
||||
bdic['old_growth_spruce_taiga'] = bdic['giant_spruce_taiga']
|
||||
bdic['snowy_plains'] = bdic['snowy_tundra']
|
||||
bdic['sparse_jungle'] = bdic['jungle_edge']
|
||||
bdic['stony_shore'] = bdic['stone_shore']
|
||||
bdic['windswept_hills'] = bdic['mountains']
|
||||
bdic['windswept_forest'] = bdic['wooded_mountains']
|
||||
bdic['windswept_gravelly_hills'] = bdic['gravelly_mountains']
|
||||
bdic['windswept_savanna'] = bdic['shattered_savanna']
|
||||
bdic['wooded_badlands'] = bdic['wooded_badlands_plateau']
|
||||
# // 1.19
|
||||
bdic['deep_dark'] = 183
|
||||
bdic['mangrove_swamp'] = 184
|
||||
# // 1.20
|
||||
bdic['cherry_grove'] = 185
|
||||
|
||||
|
||||
with open(in_file) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
ln = [re.sub(r'/\*[0-9]*\*/','',x) for x in lines]
|
||||
ln = [re.sub(r'[\{\}]','',x) for x in ln]
|
||||
ln = [re.sub(r',,',',',x)[:-1] for x in ln]
|
||||
ln = [x for x in ln if len(x) > 0]
|
||||
ln[0] = '0,0,0,0,0,0,0,0,0,0,0,0'+ln[0]
|
||||
|
||||
ln = [l[:-1].split(',') for l in ln]
|
||||
np = [[(int(x[i]),int(x[i+1])) for i in range(0,12,2)] + x[12:] for x in ln]
|
||||
nps = set()
|
||||
for x in np:
|
||||
for n in x[:6]:
|
||||
nps.add(n)
|
||||
|
||||
nps = sorted(list(nps))
|
||||
npdic = dict()
|
||||
for i in range(len(nps)):
|
||||
npdic[nps[i]] = i
|
||||
|
||||
for i,n in enumerate(nps):
|
||||
s = '{{{:6d},{:6d}}}'.format(n[0],n[1])
|
||||
print(s,end=',')
|
||||
if i%4 ==3:
|
||||
print(' // {:02X}-{:02X}'.format(i-3, i))
|
||||
print ('\n')
|
||||
|
||||
bp = []
|
||||
for i,x in enumerate(np):
|
||||
p = ['{:02X}'.format(npdic[p]) for p in x[:6]]
|
||||
p.reverse()
|
||||
if len(x) == 7:
|
||||
da = 0xFF00 + bdic[x[6]]
|
||||
else:
|
||||
da = int(x[6])
|
||||
s = '0x'+'{:04X}'.format(da)+''.join(p)
|
||||
print(s,end=',')
|
||||
if i % 4 == 0:
|
||||
print()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
115
docs/nptree_c.py
Normal file
115
docs/nptree_c.py
Normal file
@ -0,0 +1,115 @@
|
||||
import sys
|
||||
import re
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
msg = \
|
||||
"""
|
||||
usage: {0} FILE
|
||||
Converts a dump of the tree structure inside biomeEntries, obtained with
|
||||
the debugger of IntelliJ IDEA, into a C representation. Currently setup
|
||||
the script assumes a tree of order 6, used by 1.19.3 - 1.20.
|
||||
""".format(sys.argv[0])
|
||||
print(msg)
|
||||
sys.exit(0)
|
||||
|
||||
in_file = sys.argv[1]
|
||||
|
||||
with open(in_file) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
|
||||
def torange(x):
|
||||
if x[0] == '[':
|
||||
m = re.search(r'(-?[0-9]+)-(-?[0-9]+)', x)
|
||||
return int(m.group(1)), int(m.group(2))
|
||||
if x[-1] == ']':
|
||||
x = x[:-1]
|
||||
return int(x), int(x)
|
||||
|
||||
"""
|
||||
|
||||
typedef struct Node Node;
|
||||
struct Node
|
||||
{
|
||||
short range[12];
|
||||
short inner[10];
|
||||
short biome;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
class Node:
|
||||
def __init__(self):
|
||||
self.range = None
|
||||
self.inner = []
|
||||
self.biome = None
|
||||
self.id = 0
|
||||
|
||||
def set(self, r, b, idx):
|
||||
if len(idx) > 0:
|
||||
i = idx[0]
|
||||
while i >= len(self.inner):
|
||||
self.inner.append(Node())
|
||||
self.inner[i].set(r, b, idx[1:])
|
||||
else:
|
||||
if r:
|
||||
self.range = r
|
||||
if b:
|
||||
self.biome = b
|
||||
|
||||
def dump(self, depth = 0):
|
||||
print ('{} : {}'.format(self.range, self.biome))
|
||||
for i,n in enumerate(self.inner):
|
||||
print ('{}[{}]:'.format(' '*depth, i), end='')
|
||||
n.dump(depth+1)
|
||||
|
||||
def gen_ids(self, num):
|
||||
self.id = num
|
||||
num += 1
|
||||
for n in self.inner:
|
||||
num = n.gen_ids(num)
|
||||
return num
|
||||
|
||||
def dump_c(self):
|
||||
s = '/*{}*/{{'.format(self.id)
|
||||
if self.range:
|
||||
s += '{' + ','.join(['{},{}'.format(r[0], r[1]) for r in self.range[:-1]]) + '},'
|
||||
else:
|
||||
s += '{},'
|
||||
s += '{' + ','.join(['{}'.format(n.id) for n in self.inner]) + '},'
|
||||
if self.biome:
|
||||
s += self.biome + '},'
|
||||
else:
|
||||
s += 'none},'
|
||||
print (s)
|
||||
for n in self.inner:
|
||||
n.dump_c()
|
||||
|
||||
|
||||
tree = Node()
|
||||
idx = [0,0,0,0,0]
|
||||
lo = -1
|
||||
|
||||
|
||||
while lo+1 < len(lines):
|
||||
lo += 1
|
||||
m = re.search(r'([ ]+)([0-9]+) = {MultiNoiseUtil[^\[]+\[([0-9\-\[\]]+), ([0-9\-\[\]]+), ([0-9\-\[\]]+), ([0-9\-\[\]]+), ([0-9\-\[\]]+), ([0-9\-\[\]]+), ([0-9\-\[\]]+)', lines[lo])
|
||||
if not m:
|
||||
continue
|
||||
dim = (len(m.group(1))-1) // 2
|
||||
idx[dim] = int(m.group(2))
|
||||
r = [torange(m.group(i)) for i in [3,4,5,6,7,8,9]]
|
||||
b = re.search(r'worldgen/biome / minecraft:([a-z_]+)', lines[lo+1])
|
||||
if b:
|
||||
b = b.group(1)
|
||||
tree.set(r, b, idx[:(dim+1)])
|
||||
|
||||
tree.gen_ids(0)
|
||||
tree.dump_c()
|
||||
print()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
31
finders.c
31
finders.c
@ -530,6 +530,8 @@ int isStrongholdBiome(int mc, int id)
|
||||
case snowy_beach:
|
||||
case swamp_hills:
|
||||
return 0;
|
||||
case mushroom_field_shore:
|
||||
return mc >= MC_1_13;
|
||||
case stone_shore:
|
||||
return mc <= MC_1_17;
|
||||
case bamboo_jungle:
|
||||
@ -590,7 +592,7 @@ int nextStronghold(StrongholdIter *sh, const Generator *g)
|
||||
validM |= (1ULL << i);
|
||||
}
|
||||
|
||||
if (sh->mc >= MC_1_19_3)
|
||||
if (sh->mc > MC_1_19_2)
|
||||
{
|
||||
if (g)
|
||||
{
|
||||
@ -727,10 +729,11 @@ uint64_t getSpawnDist(const Generator *g, int x, int z)
|
||||
static
|
||||
void findFittest(const Generator *g, Pos *pos, uint64_t *fitness, double maxrad, double step)
|
||||
{
|
||||
double rad, ang;
|
||||
Pos p = *pos;
|
||||
for (double rad = step; rad <= maxrad; rad += step)
|
||||
for (rad = step; rad <= maxrad; rad += step)
|
||||
{
|
||||
for (double ang = 0; ang <= PI*2; ang += step/rad)
|
||||
for (ang = 0; ang <= PI*2; ang += step/rad)
|
||||
{
|
||||
int x = p.x + (int)(sin(ang) * rad);
|
||||
int z = p.z + (int)(cos(ang) * rad);
|
||||
@ -739,7 +742,7 @@ void findFittest(const Generator *g, Pos *pos, uint64_t *fitness, double maxrad,
|
||||
uint64_t fit = (uint64_t)(d*d * 1e8);
|
||||
// Calculate portion of fitness dependent on climate values
|
||||
fit += getSpawnDist(g, x, z);
|
||||
// Then updates pos and fitness if combined total is lower ( = better) than previous best fitness
|
||||
// Then update pos and fitness if combined total is lower/better
|
||||
if (fit < *fitness)
|
||||
{
|
||||
pos->x = x;
|
||||
@ -4734,6 +4737,16 @@ static const int g_biome_para_range_19_diff[][13] = {
|
||||
{mangrove_swamp , 2000, IMAX, IMIN, IMAX, -1100, IMAX, 5500, IMAX, IMIN, IMAX, IMIN, IMAX},
|
||||
};
|
||||
|
||||
static const int g_biome_para_range_20_diff[][13] = {
|
||||
{swamp , -4500, 2000, IMIN, IMAX, -1100, IMAX, 5500, IMAX, IMIN, IMAX, IMIN, IMAX},
|
||||
{grove , IMIN, 2000, -1000, IMAX, -1899, IMAX, IMIN,-3750, IMIN,10500, IMIN, IMAX},
|
||||
{snowy_slopes , IMIN, 2000, IMIN,-1000, -1899, IMAX, IMIN,-3750, IMIN,10500, IMIN, IMAX},
|
||||
{jagged_peaks , IMIN, 2000, IMIN, IMAX, -1899, IMAX, IMIN,-3750, IMIN,10500, -9333,-4000},
|
||||
{frozen_peaks , IMIN, 2000, IMIN, IMAX, -1899, IMAX, IMIN,-3750, IMIN,10500, 4000, 9333},
|
||||
{stony_peaks , 2000, 5500, IMIN, IMAX, -1899, IMAX, IMIN,-3750, IMIN,10500, -9333, 9333},
|
||||
{cherry_grove , -4500, 2000, IMIN,-1000, 300, IMAX, -7799, 500, IMIN, IMAX, 2666, IMAX},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the min/max parameter values within which a biome change can occur.
|
||||
@ -4763,6 +4776,15 @@ const int *getBiomeParaLimits(int mc, int id)
|
||||
if (mc <= MC_1_17)
|
||||
return NULL;
|
||||
int i, n;
|
||||
if (mc > MC_1_19)
|
||||
{
|
||||
n = sizeof(g_biome_para_range_20_diff) / sizeof(g_biome_para_range_20_diff[0]);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (g_biome_para_range_20_diff[i][0] == id)
|
||||
return &g_biome_para_range_20_diff[i][1];
|
||||
}
|
||||
}
|
||||
if (mc > MC_1_18)
|
||||
{
|
||||
n = sizeof(g_biome_para_range_19_diff) / sizeof(g_biome_para_range_19_diff[0]);
|
||||
@ -4772,7 +4794,6 @@ const int *getBiomeParaLimits(int mc, int id)
|
||||
return &g_biome_para_range_19_diff[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
n = sizeof(g_biome_para_range_18) / sizeof(g_biome_para_range_18[0]);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
|
30
generator.c
30
generator.c
@ -142,13 +142,14 @@ size_t getMinCacheSize(const Generator *g, int scale, int sx, int sy, int sz)
|
||||
if (sy == 0)
|
||||
sy = 1;
|
||||
size_t len = (size_t)sx * sz * sy;
|
||||
if (g->mc <= MC_B1_7 && scale <=4 && !(g->flags & NO_BETA_OCEAN))
|
||||
if (g->mc <= MC_B1_7 && scale <= 4 && !(g->flags & NO_BETA_OCEAN))
|
||||
{
|
||||
int sxa = (sx >> (2>>(scale>>1))) + 1;
|
||||
int sza = (sz >> (2>>(scale>>1))) + 1;
|
||||
len += ((((sxa <= sza) ? sxa : sza) << 1) + 1)*sizeof(SeaLevelColumnNoiseBeta);
|
||||
int cellwidth = scale >> 1;
|
||||
int smin = (sx < sz ? sx : sz);
|
||||
int slen = (((smin >> (2 >> cellwidth)) + 1) << 1) + 1;
|
||||
len += slen * sizeof(SeaLevelColumnNoiseBeta);
|
||||
}
|
||||
if (g->mc >= MC_B1_8 && g->mc <= MC_1_17 && g->dim == DIM_OVERWORLD)
|
||||
else if (g->mc >= MC_B1_8 && g->mc <= MC_1_17 && g->dim == DIM_OVERWORLD)
|
||||
{ // recursively check the layer stack for the max buffer
|
||||
const Layer *entry = getLayerForScale(g, scale);
|
||||
if (!entry) {
|
||||
@ -158,7 +159,7 @@ size_t getMinCacheSize(const Generator *g, int scale, int sx, int sy, int sz)
|
||||
size_t len2d = getMinLayerCacheSize(entry, sx, sz);
|
||||
len += len2d - sx*sz;
|
||||
}
|
||||
else if (g->mc >= MC_1_18 && scale <= 1)
|
||||
else if ((g->mc >= MC_1_18 || g->dim != DIM_OVERWORLD) && scale <= 1)
|
||||
{ // allocate space for temporary copy of voronoi source
|
||||
sx = ((sx+3) >> 2) + 2;
|
||||
sy = ((sy+3) >> 2) + 2;
|
||||
@ -629,6 +630,23 @@ int mapApproxHeight(float *y, int *ids, const Generator *g, const SurfaceNoise *
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (g->mc <= MC_B1_7)
|
||||
{
|
||||
SurfaceNoiseBeta snb; // TODO: merge SurfaceNoise and SurfaceNoiseBeta?
|
||||
initSurfaceNoiseBeta(&snb, g->seed);
|
||||
int i, j;
|
||||
for (j = 0; j < h; j++)
|
||||
{
|
||||
for (i = 0; i < w; i++)
|
||||
{
|
||||
int samplex = ((x + i) << 2) + 2;
|
||||
int samplez = ((z + j) << 2) + 2;
|
||||
// TODO: properly implement beta surface finder
|
||||
y[j*w+i] = approxSurfaceBeta(&g->bnb, &snb, samplex, samplez);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float biome_kernel[25] = { // with 10 / (sqrt(i**2 + j**2) + 0.2)
|
||||
3.302044127, 4.104975761, 4.545454545, 4.104975761, 3.302044127,
|
||||
|
45
layers.c
45
layers.c
@ -19,6 +19,9 @@ int biomeExists(int mc, int id)
|
||||
if (id >= small_end_islands && id <= end_barrens)
|
||||
return 1;
|
||||
|
||||
if (id == cherry_grove)
|
||||
return mc >= MC_1_20;
|
||||
|
||||
if (id == deep_dark || id == mangrove_swamp)
|
||||
return mc >= MC_1_19_2;
|
||||
|
||||
@ -201,7 +204,7 @@ int isOverworld(int mc, int id)
|
||||
case deep_warm_ocean:
|
||||
case the_void:
|
||||
return 0;
|
||||
case tall_birch_hills:
|
||||
case tall_birch_forest:
|
||||
return mc <= MC_1_8 || mc >= MC_1_11;
|
||||
case dripstone_caves:
|
||||
case lush_caves:
|
||||
@ -1263,7 +1266,7 @@ void setBetaBiomeSeed(BiomeNoiseBeta *bnb, uint64_t seed)
|
||||
}
|
||||
|
||||
|
||||
enum { CONTINENTALNESS, EROSION, RIDGES, WEIRDNESS };
|
||||
enum { SP_CONTINENTALNESS, SP_EROSION, SP_RIDGES, SP_WEIRDNESS };
|
||||
|
||||
static void addSplineVal(Spline *rsp, float loc, Spline *val, float der)
|
||||
{
|
||||
@ -1300,7 +1303,7 @@ static float getOffsetValue(float weirdness, float continentalness)
|
||||
static Spline *createSpline_38219(SplineStack *ss, float f, int bl)
|
||||
{
|
||||
Spline *sp = &ss->stack[ss->len++];
|
||||
sp->typ = RIDGES;
|
||||
sp->typ = SP_RIDGES;
|
||||
|
||||
float i = getOffsetValue(-1.0F, f);
|
||||
float k = getOffsetValue( 1.0F, f);
|
||||
@ -1342,7 +1345,7 @@ static Spline *createFlatOffsetSpline(
|
||||
SplineStack *ss, float f, float g, float h, float i, float j, float k)
|
||||
{
|
||||
Spline *sp = &ss->stack[ss->len++];
|
||||
sp->typ = RIDGES;
|
||||
sp->typ = SP_RIDGES;
|
||||
|
||||
float l = 0.5F * (g - f); if (l < k) l = k;
|
||||
float m = 5.0F * (h - g);
|
||||
@ -1369,14 +1372,14 @@ static Spline *createLandSpline(
|
||||
Spline *sp7 = createFlatOffsetSpline(ss, f, j, j, g, h, 0.5F);
|
||||
|
||||
Spline *sp8 = &ss->stack[ss->len++];
|
||||
sp8->typ = RIDGES;
|
||||
sp8->typ = SP_RIDGES;
|
||||
addSplineVal(sp8, -1.0F, createFixSpline(ss, f), 0.0F);
|
||||
addSplineVal(sp8, -0.4F, sp6, 0.0F);
|
||||
addSplineVal(sp8, 0.0F, createFixSpline(ss, h + 0.07F), 0.0F);
|
||||
|
||||
Spline *sp9 = createFlatOffsetSpline(ss, -0.02F, k, k, g, h, 0.0F);
|
||||
Spline *sp = &ss->stack[ss->len++];
|
||||
sp->typ = EROSION;
|
||||
sp->typ = SP_EROSION;
|
||||
addSplineVal(sp, -0.85F, sp1, 0.0F);
|
||||
addSplineVal(sp, -0.7F, sp2, 0.0F);
|
||||
addSplineVal(sp, -0.4F, sp3, 0.0F);
|
||||
@ -1436,7 +1439,7 @@ void initBiomeNoise(BiomeNoise *bn, int mc)
|
||||
SplineStack *ss = &bn->ss;
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
Spline *sp = &ss->stack[ss->len++];
|
||||
sp->typ = CONTINENTALNESS;
|
||||
sp->typ = SP_CONTINENTALNESS;
|
||||
|
||||
Spline *sp1 = createLandSpline(ss, -0.15F, 0.00F, 0.0F, 0.1F, 0.00F, -0.03F, 0);
|
||||
Spline *sp2 = createLandSpline(ss, -0.10F, 0.03F, 0.1F, 0.1F, 0.01F, -0.03F, 0);
|
||||
@ -1703,7 +1706,7 @@ int genBiomeNoiseScaled(const BiomeNoise *bn, int *out, Range r, uint64_t sha)
|
||||
}
|
||||
|
||||
static void genColumnNoise(const SurfaceNoiseBeta *snb, SeaLevelColumnNoiseBeta *dest,
|
||||
int cx, int cz, double lacmin)
|
||||
double cx, double cz, double lacmin)
|
||||
{
|
||||
dest->contASample = sampleOctaveAmp(&snb->octcontA, cx, 0, cz, 0, 0, 1);
|
||||
dest->contBSample = sampleOctaveAmp(&snb->octcontB, cx, 0, cz, 0, 0, 1);
|
||||
@ -1770,33 +1773,45 @@ static double lerp4(
|
||||
return b0 + (b1 - b0) * dx;
|
||||
}
|
||||
|
||||
double approxSurfaceBeta(const BiomeNoiseBeta *bnb, const SurfaceNoiseBeta *snb,
|
||||
int x, int z)
|
||||
{
|
||||
// TODO: sample vertically to get a more accurate height value
|
||||
double climate[2];
|
||||
sampleBiomeNoiseBeta(bnb, NULL, climate, x, z);
|
||||
double cols[2];
|
||||
SeaLevelColumnNoiseBeta colNoise;
|
||||
genColumnNoise(snb, &colNoise, x*0.25, z*0.25, 0);
|
||||
processColumnNoise(cols, &colNoise, climate);
|
||||
return 63 + (cols[0]*0.125 + cols[1]*0.875) * 0.5;
|
||||
}
|
||||
|
||||
int genBiomeNoiseBetaScaled(const BiomeNoiseBeta *bnb,
|
||||
const SurfaceNoiseBeta *snb, int *out, Range r)
|
||||
{
|
||||
if (!snb || r.scale >= 4)
|
||||
{
|
||||
int i, j;
|
||||
int *p = out;
|
||||
int mid = r.scale >> 1;
|
||||
for (j = 0; j < r.sz; j++)
|
||||
{
|
||||
int z = (r.z+j)*r.scale + mid;
|
||||
for (i = 0; i < r.sx; i++)
|
||||
{
|
||||
int x = (r.x+i)*r.scale + mid;
|
||||
double climate[2];
|
||||
*p = sampleBiomeNoiseBeta(bnb, NULL, climate, x, z);
|
||||
int x = (r.x+i)*r.scale + mid;
|
||||
int id = sampleBiomeNoiseBeta(bnb, NULL, climate, x, z);
|
||||
|
||||
if (snb)
|
||||
{
|
||||
double cols[2];
|
||||
SeaLevelColumnNoiseBeta colNoise;
|
||||
genColumnNoise(snb, &colNoise, x>>2, z>>2, 4.0 / r.scale);
|
||||
genColumnNoise(snb, &colNoise, x*0.25, z*0.25, 4.0/r.scale);
|
||||
processColumnNoise(cols, &colNoise, climate);
|
||||
if (cols[0]*0.125 + cols[1] <= 0)
|
||||
*p = (climate[0] < 0.5) ? frozen_ocean : ocean;
|
||||
if (cols[0]*0.125 + cols[1]*0.875 <= 0)
|
||||
id = (climate[0] < 0.5) ? frozen_ocean : ocean;
|
||||
}
|
||||
p++;
|
||||
out[j*r.sx + i] = id;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
9
layers.h
9
layers.h
@ -36,7 +36,9 @@ enum MCVersion
|
||||
MC_1_17_1, MC_1_17 = MC_1_17_1,
|
||||
MC_1_18_2, MC_1_18 = MC_1_18_2,
|
||||
MC_1_19_2,
|
||||
MC_1_19_3, MC_1_19 = MC_1_19_3, MC_NEWEST = MC_1_19,
|
||||
MC_1_19, // 1.19.3 - 1.19.4
|
||||
MC_1_20,
|
||||
MC_NEWEST = MC_1_20,
|
||||
};
|
||||
|
||||
enum Dimension
|
||||
@ -169,6 +171,8 @@ enum BiomeID
|
||||
// 1.19
|
||||
deep_dark = 183,
|
||||
mangrove_swamp = 184,
|
||||
// 1.20
|
||||
cherry_grove = 185,
|
||||
};
|
||||
|
||||
|
||||
@ -526,6 +530,9 @@ int sampleBiomeNoise(const BiomeNoise *bn, int64_t *np, int x, int y, int z,
|
||||
uint64_t *dat, uint32_t sample_flags);
|
||||
int sampleBiomeNoiseBeta(const BiomeNoiseBeta *bnb, int64_t *np, double *nv,
|
||||
int x, int z);
|
||||
double approxSurfaceBeta(const BiomeNoiseBeta *bnb, const SurfaceNoiseBeta *snb,
|
||||
int x, int z); // doesn't really work yet
|
||||
|
||||
/**
|
||||
* (Alpha 1.2 - Beta 1.7)
|
||||
* Temperature and humidity values to biome.
|
||||
|
27
tests.c
27
tests.c
@ -322,7 +322,7 @@ void findBiomeParaBounds()
|
||||
}
|
||||
|
||||
Generator g;
|
||||
setupGenerator(&g, MC_1_18, 0);
|
||||
setupGenerator(&g, MC_1_20, 0);
|
||||
int64_t s;
|
||||
int r = 1000;
|
||||
for (s = 0; s < 20000; s++)
|
||||
@ -341,10 +341,10 @@ void findBiomeParaBounds()
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (!isOverworld(MC_1_18, i))
|
||||
if (!isOverworld(MC_1_20, i))
|
||||
continue;
|
||||
|
||||
printf("{%-24s", biome2str(MC_1_18, i));
|
||||
printf("{%-24s", biome2str(MC_1_20, i));
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
printf(", %6ld,%6ld", bbounds[i][j][0], bbounds[i][j][1]);
|
||||
@ -465,22 +465,13 @@ void findStructures(int structureType, int mc, int dim, uint64_t seed,
|
||||
|
||||
int main()
|
||||
{
|
||||
int mc = MC_B1_7;
|
||||
for (int i = 1; i <= 16; i *= 4)
|
||||
{
|
||||
double t = -now();
|
||||
uint32_t h = getRef(mc, DIM_OVERWORLD, 7, i, 1, NULL);
|
||||
t += now();
|
||||
printf("1:%-2d: %08x t = %-8.4f\n", i, h, t);
|
||||
}
|
||||
|
||||
testAreas(mc, 0, 1);
|
||||
testAreas(mc, 0, 4);
|
||||
testAreas(mc, 0, 16);
|
||||
testAreas(mc, 0, 256);
|
||||
//testAreas(mc, 0, 1);
|
||||
//testAreas(mc, 0, 4);
|
||||
//testAreas(mc, 0, 16);
|
||||
//testAreas(mc, 0, 256);
|
||||
//testCanBiomesGenerate();
|
||||
testGeneration();
|
||||
//findBiomeParaBounds();
|
||||
//testGeneration();
|
||||
findBiomeParaBounds();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
25
util.c
25
util.c
@ -72,12 +72,14 @@ const char* mc2str(int mc)
|
||||
case MC_1_18: return "1.18"; break;
|
||||
case MC_1_19_2: return "1.19.2"; break;
|
||||
case MC_1_19: return "1.19"; break;
|
||||
case MC_1_20: return "1.20"; break;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int str2mc(const char *s)
|
||||
{
|
||||
if (!strcmp(s, "1.20")) return MC_1_20;
|
||||
if (!strcmp(s, "1.19")) return MC_1_19;
|
||||
if (!strcmp(s, "1.19.2")) return MC_1_19_2;
|
||||
if (!strcmp(s, "1.18")) return MC_1_18;
|
||||
@ -236,6 +238,8 @@ const char *biome2str(int mc, int id)
|
||||
// 1.19
|
||||
case deep_dark: return "deep_dark";
|
||||
case mangrove_swamp: return "mangrove_swamp";
|
||||
// 1.20
|
||||
case cherry_grove: return "cherry_grove";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -354,18 +358,19 @@ void initBiomeColors(unsigned char biomeColors[256][3])
|
||||
setBiomeColor(biomeColors, warped_forest, 73, 144, 123);
|
||||
setBiomeColor(biomeColors, basalt_deltas, 100, 95, 99);
|
||||
|
||||
setBiomeColor(biomeColors, dripstone_caves, 78, 48, 18); // TBD
|
||||
setBiomeColor(biomeColors, lush_caves, 40, 60, 0); // TBD
|
||||
setBiomeColor(biomeColors, dripstone_caves, 78, 48, 18);
|
||||
setBiomeColor(biomeColors, lush_caves, 40, 60, 0);
|
||||
|
||||
setBiomeColor(biomeColors, meadow, 96, 164, 69); // TBD
|
||||
setBiomeColor(biomeColors, grove, 71, 114, 108); // TBD
|
||||
setBiomeColor(biomeColors, snowy_slopes, 196, 196, 196); // TBD
|
||||
setBiomeColor(biomeColors, stony_peaks, 123, 143, 116); // TBD
|
||||
setBiomeColor(biomeColors, jagged_peaks, 220, 220, 200); // TBD
|
||||
setBiomeColor(biomeColors, frozen_peaks, 176, 179, 206); // TBD
|
||||
setBiomeColor(biomeColors, meadow, 96, 164, 69);
|
||||
setBiomeColor(biomeColors, grove, 71, 114, 108);
|
||||
setBiomeColor(biomeColors, snowy_slopes, 196, 196, 196);
|
||||
setBiomeColor(biomeColors, stony_peaks, 123, 143, 116);
|
||||
setBiomeColor(biomeColors, jagged_peaks, 220, 220, 200);
|
||||
setBiomeColor(biomeColors, frozen_peaks, 176, 179, 206);
|
||||
|
||||
setBiomeColor(biomeColors, deep_dark, 3, 31, 41); // TBD
|
||||
setBiomeColor(biomeColors, mangrove_swamp, 44, 204, 142); // TBD
|
||||
setBiomeColor(biomeColors, deep_dark, 3, 31, 41);
|
||||
setBiomeColor(biomeColors, mangrove_swamp, 44, 204, 142);
|
||||
setBiomeColor(biomeColors, cherry_grove, 255, 145, 200);
|
||||
}
|
||||
|
||||
void initBiomeTypeColors(unsigned char biomeColors[256][3])
|
||||
|
Loading…
x
Reference in New Issue
Block a user