Add fallback noises when Minetest doesn't give it
[minetest_biomeinfo.git] / init.lua
blob5013647ed250364b96eeb62224f9e1e2e6899fdd
1 biomeinfo = {}
3 -- Copied from mapgen_v6.h
4 local MGV6_FREQ_HOT = 0.4
5 local MGV6_FREQ_SNOW = -0.4
6 local MGV6_FREQ_TAIGA = 0.5
7 local MGV6_FREQ_JUNGLE = 0.5
9 -- Biome types
10 local BT_NORMAL = "Normal"
11 local BT_TUNDRA = "Tundra"
12 local BT_TAIGA = "Taiga"
13 local BT_DESERT = "Desert"
14 local BT_JUNGLE = "Jungle"
16 -- Get mapgen settings
18 local seed = tonumber(minetest.get_mapgen_setting("seed")) or 0
20 local mgv6_perlin_biome, mgv6_perlin_humidity, mgv6_np_biome
22 -- v6 default noiseparams are hardcoded here because Minetest doesn't give us those
23 local mgv6_np_biome_default = {
24 offset = 0,
25 scale = 1,
26 spread = { x = 500, y = 500, z = 500},
27 seed = 9130,
28 octaves = 3,
29 persistence = 0.50,
30 lacunarity = 2.0,
31 flags = "eased",
33 local mgv6_np_humidity_default = {
34 offset = 0.5,
35 scale = 0.5,
36 spread = { x = 500, y = 500, z = 500},
37 seed = 72384,
38 octaves = 3,
39 persistence = 0.50,
40 lacunarity = 2.0,
41 flags = "eased",
44 local v6_flags_str = minetest.get_mapgen_setting("mgv6_spflags")
45 if v6_flags_str == nil then
46 v6_flags_str = ""
47 end
48 local v6_flags = string.split(v6_flags_str)
49 local v6_use_snow_biomes = true
50 local v6_use_jungles = true
51 -- TODO: Implement biome blend.
52 -- Currently we pretend biome blend is disabled.
53 -- This just makes the calculations inaccurate near biome boundaries,
54 -- but should be fine otherwise.
55 local v6_use_biome_blend = false
56 for f=1, #v6_flags do
57 local flag = v6_flags[f]:trim()
58 if flag == "nosnowbiomes" then
59 v6_use_snow_biomes = false
60 end
61 if flag == "snowbiomes" then
62 v6_use_snow_biomes = true
63 end
64 if flag == "nojungles" then
65 v6_use_jungles = false
66 end
67 if flag == "jungles" then
68 v6_use_jungles = true
69 end
70 if flag == "nobiomeblend" then
71 v6_use_biome_blend = false
72 end
73 -- TODO
74 -- if flag == "biomeblend" then
75 -- v6_use_biome_blend = true
76 -- end
77 end
78 -- Force-enable jungles when snowbiomes flag is set
79 if v6_use_snow_biomes then
80 v6_use_jungles = true
81 end
82 local v6_freq_desert = tonumber(minetest.get_mapgen_setting("mgv6_freq_desert") or 0.45)
84 local NOISE_MAGIC_X = 1619
85 local NOISE_MAGIC_Y = 31337
86 local NOISE_MAGIC_Z = 52591
87 local NOISE_MAGIC_SEED = 1013
88 local noise2d = function(x, y, seed)
89 -- TODO: implement noise2d function for biome blend
90 return 0
91 --[[
92 local n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y
93 + NOISE_MAGIC_SEED * seed) & 0x7fffffff;
94 n = (n >> 13) ^ n;
95 n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
96 return 1.0 - n / 0x40000000;
98 end
100 biomeinfo.all_v6_biomes = {
101 BT_NORMAL,
102 BT_DESERT,
103 BT_JUNGLE,
104 BT_TUNDRA,
105 BT_TAIGA
108 local function init_perlins()
109 if not mgv6_perlin_biome then
110 mgv6_np_biome = minetest.get_mapgen_setting_noiseparams("mgv6_np_biome")
111 if not mgv6_np_biome then
112 mgv6_np_biome = mgv6_np_biome_default
113 minetest.log("action", "[biomeinfo] Using hardcoded mgv6_np_biome default")
115 mgv6_perlin_biome = minetest.get_perlin(mgv6_np_biome)
117 if not mgv6_perlin_humidity then
118 local np_humidity = minetest.get_mapgen_setting_noiseparams("mgv6_np_humidity")
119 if not np_humidity then
120 np_humidity = mgv6_np_humidity_default
121 minetest.log("action", "[biomeinfo] Using hardcoded mgv6_np_humidity default")
123 mgv6_perlin_humidity = minetest.get_perlin(np_humidity)
127 function biomeinfo.get_active_v6_biomes()
128 local biomes = { BT_NORMAL, BT_DESERT }
129 if v6_use_jungles then
130 table.insert(biomes, BT_JUNGLE)
132 if v6_use_snow_biomes then
133 table.insert(biomes, BT_TUNDRA)
134 table.insert(biomes, BT_TAIGA)
136 return biomes
139 function biomeinfo.get_v6_heat(pos)
140 init_perlins()
141 if not mgv6_perlin_biome then
142 return nil
144 local bpos = vector.floor(pos)
145 -- The temperature noise needs a special offset (see calculateNoise in mapgen_v6.cpp)
146 return mgv6_perlin_biome:get_2d({x=bpos.x + mgv6_np_biome.spread.x*0.6, y=bpos.z + mgv6_np_biome.spread.z*0.2})
149 function biomeinfo.get_v6_humidity(pos)
150 init_perlins()
151 if not mgv6_perlin_humidity then
152 return nil
154 local bpos = vector.floor(pos)
155 return mgv6_perlin_humidity:get_2d({x=bpos.x, y=bpos.z})
158 -- Returns the v6 biome at pos.
159 -- Returns a string representing the biome name.
160 function biomeinfo.get_v6_biome(pos)
161 init_perlins()
162 local bpos = vector.floor(pos)
163 -- Based on the algorithm MapgenV6::getBiome in mapgen_v6.cpp
165 local pos2d = {x=bpos.x, y=bpos.z}
166 if not mgv6_perlin_biome or not mgv6_perlin_humidity then
167 return "???"
169 local d = biomeinfo.get_v6_heat(bpos)
170 local h = biomeinfo.get_v6_humidity(bpos)
172 if (v6_use_snow_biomes) then
173 local blend
174 if v6_use_biome_blend then
175 blend = noise2d(pos2d.x, pos2d.y, seed) / 40
176 else
177 blend = 0
180 if (d > MGV6_FREQ_HOT + blend) then
181 if (h > MGV6_FREQ_JUNGLE + blend) then
182 return BT_JUNGLE
184 return BT_DESERT
186 if (d < MGV6_FREQ_SNOW + blend) then
187 if (h > MGV6_FREQ_TAIGA + blend) then
188 return BT_TAIGA
190 return BT_TUNDRA
192 return BT_NORMAL
195 if (d > v6_freq_desert) then
196 return BT_DESERT
199 if ((v6_use_biome_blend) and (d > v6_freq_desert - 0.10) and
200 ((noise2d(pos2d.x, pos2d.y, seed) + 1.0) > (v6_freq_desert - d) * 20.0)) then
201 return BT_DESERT
204 if ((v6_use_jungles) and (h > 0.75)) then
205 return BT_JUNGLE
208 return BT_NORMAL