Import source (dev state between 1.2.0 and 1.3.0)
[minetest_tutorial_subgame.git] / mods / default / mapgen.lua
blobff2b08a9d8ac33a5ba230319396137436371bdae
1 -- mods/default/mapgen.lua
3 --
4 -- Aliases for map generator outputs
5 --
7 minetest.register_alias("mapgen_stone", "default:stone")
8 minetest.register_alias("mapgen_tree", "default:tree")
9 minetest.register_alias("mapgen_leaves", "default:leaves")
10 minetest.register_alias("mapgen_jungletree", "default:jungletree")
11 minetest.register_alias("mapgen_jungleleaves", "default:jungleleaves")
12 minetest.register_alias("mapgen_apple", "default:apple")
13 minetest.register_alias("mapgen_water_source", "default:water_source")
14 minetest.register_alias("mapgen_dirt", "default:dirt")
15 minetest.register_alias("mapgen_sand", "default:sand")
16 minetest.register_alias("mapgen_gravel", "default:gravel")
17 minetest.register_alias("mapgen_clay", "default:stone")
18 minetest.register_alias("mapgen_lava_source", "default:lava_source")
19 minetest.register_alias("mapgen_cobble", "default:cobble")
20 minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
21 minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
22 minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
23 minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
24 minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
25 minetest.register_alias("mapgen_mese", "default:stone")
26 minetest.register_alias("mapgen_desert_sand", "default:desert_sand")
27 minetest.register_alias("mapgen_desert_stone", "default:desert_stone")
28 minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble")
31 -- Ore generation
34 minetest.register_ore({
35 ore_type = "scatter",
36 ore = "default:stone_with_coal",
37 wherein = "default:stone",
38 clust_scarcity = 8*8*8,
39 clust_num_ores = 8,
40 clust_size = 3,
41 height_min = -31000,
42 height_max = 64,
45 minetest.register_ore({
46 ore_type = "scatter",
47 ore = "default:stone_with_coal",
48 wherein = "default:stone",
49 clust_scarcity = 24*24*24,
50 clust_num_ores = 27,
51 clust_size = 6,
52 height_min = -31000,
53 height_max = 0,
54 flags = "absheight",
57 minetest.register_ore({
58 ore_type = "scatter",
59 ore = "default:stone_with_iron",
60 wherein = "default:stone",
61 clust_scarcity = 12*12*12,
62 clust_num_ores = 3,
63 clust_size = 2,
64 height_min = -15,
65 height_max = 2,
68 minetest.register_ore({
69 ore_type = "scatter",
70 ore = "default:stone_with_iron",
71 wherein = "default:stone",
72 clust_scarcity = 9*9*9,
73 clust_num_ores = 5,
74 clust_size = 3,
75 height_min = -63,
76 height_max = -16,
79 minetest.register_ore({
80 ore_type = "scatter",
81 ore = "default:stone_with_iron",
82 wherein = "default:stone",
83 clust_scarcity = 7*7*7,
84 clust_num_ores = 5,
85 clust_size = 3,
86 height_min = -31000,
87 height_max = -64,
88 flags = "absheight",
91 minetest.register_ore({
92 ore_type = "scatter",
93 ore = "default:stone_with_iron",
94 wherein = "default:stone",
95 clust_scarcity = 24*24*24,
96 clust_num_ores = 27,
97 clust_size = 6,
98 height_min = -31000,
99 height_max = -64,
100 flags = "absheight",
103 minetest.register_ore({
104 ore_type = "scatter",
105 ore = "default:stone_with_gold",
106 wherein = "default:stone",
107 clust_scarcity = 15*15*15,
108 clust_num_ores = 3,
109 clust_size = 2,
110 height_min = -255,
111 height_max = -64,
112 flags = "absheight",
115 minetest.register_ore({
116 ore_type = "scatter",
117 ore = "default:stone_with_gold",
118 wherein = "default:stone",
119 clust_scarcity = 13*13*13,
120 clust_num_ores = 5,
121 clust_size = 3,
122 height_min = -31000,
123 height_max = -256,
124 flags = "absheight",
127 minetest.register_ore({
128 ore_type = "scatter",
129 ore = "default:stone_with_diamond",
130 wherein = "default:stone",
131 clust_scarcity = 17*17*17,
132 clust_num_ores = 4,
133 clust_size = 3,
134 height_min = -255,
135 height_max = -128,
136 flags = "absheight",
139 minetest.register_ore({
140 ore_type = "scatter",
141 ore = "default:stone_with_diamond",
142 wherein = "default:stone",
143 clust_scarcity = 15*15*15,
144 clust_num_ores = 4,
145 clust_size = 3,
146 height_min = -31000,
147 height_max = -256,
148 flags = "absheight",
151 minetest.register_ore({
152 ore_type = "scatter",
153 ore = "default:stone_with_copper",
154 wherein = "default:stone",
155 clust_scarcity = 12*12*12,
156 clust_num_ores = 4,
157 clust_size = 3,
158 height_min = -63,
159 height_max = -16,
162 minetest.register_ore({
163 ore_type = "scatter",
164 ore = "default:stone_with_copper",
165 wherein = "default:stone",
166 clust_scarcity = 9*9*9,
167 clust_num_ores = 5,
168 clust_size = 3,
169 height_min = -31000,
170 height_max = -64,
171 flags = "absheight",
174 if minetest.setting_get("mg_name") == "indev" then
175 -- Floatlands and high mountains springs
176 minetest.register_ore({
177 ore_type = "scatter",
178 ore = "default:water_source",
179 ore_param2 = 128,
180 wherein = "default:stone",
181 clust_scarcity = 40*40*40,
182 clust_num_ores = 8,
183 clust_size = 3,
184 height_min = 100,
185 height_max = 31000,
188 minetest.register_ore({
189 ore_type = "scatter",
190 ore = "default:lava_source",
191 ore_param2 = 128,
192 wherein = "default:stone",
193 clust_scarcity = 50*50*50,
194 clust_num_ores = 5,
195 clust_size = 2,
196 height_min = 10000,
197 height_max = 31000,
200 minetest.register_ore({
201 ore_type = "scatter",
202 ore = "default:sand",
203 wherein = "default:stone",
204 clust_scarcity = 20*20*20,
205 clust_num_ores = 5*5*3,
206 clust_size = 5,
207 height_min = 500,
208 height_max = 31000,
211 -- Underground springs
212 minetest.register_ore({
213 ore_type = "scatter",
214 ore = "default:water_source",
215 ore_param2 = 128,
216 wherein = "default:stone",
217 clust_scarcity = 25*25*25,
218 clust_num_ores = 8,
219 clust_size = 3,
220 height_min = -10000,
221 height_max = -10,
224 minetest.register_ore({
225 ore_type = "scatter",
226 ore = "default:lava_source",
227 ore_param2 = 128,
228 wherein = "default:stone",
229 clust_scarcity = 35*35*35,
230 clust_num_ores = 5,
231 clust_size = 2,
232 height_min = -31000,
233 height_max = -100,
237 function default.generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, chunk_size, ore_per_chunk, height_min, height_max)
238 minetest.log('action', "WARNING: default.generate_ore is deprecated")
240 if maxp.y < height_min or minp.y > height_max then
241 return
243 local y_min = math.max(minp.y, height_min)
244 local y_max = math.min(maxp.y, height_max)
245 if chunk_size >= y_max - y_min + 1 then
246 return
248 local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
249 local pr = PseudoRandom(seed)
250 local num_chunks = math.floor(chunks_per_volume * volume)
251 local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
252 --print("generate_ore num_chunks: "..dump(num_chunks))
253 for i=1,num_chunks do
254 local y0 = pr:next(y_min, y_max-chunk_size+1)
255 if y0 >= height_min and y0 <= height_max then
256 local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
257 local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
258 local p0 = {x=x0, y=y0, z=z0}
259 for x1=0,chunk_size-1 do
260 for y1=0,chunk_size-1 do
261 for z1=0,chunk_size-1 do
262 if pr:next(1,inverse_chance) == 1 then
263 local x2 = x0+x1
264 local y2 = y0+y1
265 local z2 = z0+z1
266 local p2 = {x=x2, y=y2, z=z2}
267 if minetest.get_node(p2).name == wherein then
268 minetest.set_node(p2, {name=name})
276 --print("generate_ore done")
279 function default.make_papyrus(pos, size)
280 for y=0,size-1 do
281 local p = {x=pos.x, y=pos.y+y, z=pos.z}
282 local nn = minetest.get_node(p).name
283 if minetest.registered_nodes[nn] and
284 minetest.registered_nodes[nn].buildable_to then
285 minetest.set_node(p, {name="default:papyrus"})
286 else
287 return
292 function default.make_cactus(pos, size)
293 for y=0,size-1 do
294 local p = {x=pos.x, y=pos.y+y, z=pos.z}
295 local nn = minetest.get_node(p).name
296 if minetest.registered_nodes[nn] and
297 minetest.registered_nodes[nn].buildable_to then
298 minetest.set_node(p, {name="default:cactus"})
299 else
300 return
305 -- facedir: 0/1/2/3 (head node facedir value)
306 -- length: length of rainbow tail
307 function default.make_nyancat(pos, facedir, length)
308 local tailvec = {x=0, y=0, z=0}
309 if facedir == 0 then
310 tailvec.z = 1
311 elseif facedir == 1 then
312 tailvec.x = 1
313 elseif facedir == 2 then
314 tailvec.z = -1
315 elseif facedir == 3 then
316 tailvec.x = -1
317 else
318 --print("default.make_nyancat(): Invalid facedir: "+dump(facedir))
319 facedir = 0
320 tailvec.z = 1
322 local p = {x=pos.x, y=pos.y, z=pos.z}
323 minetest.set_node(p, {name="default:nyancat", param2=facedir})
324 for i=1,length do
325 p.x = p.x + tailvec.x
326 p.z = p.z + tailvec.z
327 minetest.set_node(p, {name="default:nyancat_rainbow", param2=facedir})
331 function generate_nyancats(seed, minp, maxp)
332 local height_min = -31000
333 local height_max = -32
334 if maxp.y < height_min or minp.y > height_max then
335 return
337 local y_min = math.max(minp.y, height_min)
338 local y_max = math.min(maxp.y, height_max)
339 local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
340 local pr = PseudoRandom(seed + 9324342)
341 local max_num_nyancats = math.floor(volume / (16*16*16))
342 for i=1,max_num_nyancats do
343 if pr:next(0, 1000) == 0 then
344 local x0 = pr:next(minp.x, maxp.x)
345 local y0 = pr:next(minp.y, maxp.y)
346 local z0 = pr:next(minp.z, maxp.z)
347 local p0 = {x=x0, y=y0, z=z0}
348 default.make_nyancat(p0, pr:next(0,3), pr:next(3,15))
353 minetest.register_on_generated(function(minp, maxp, seed)
354 if maxp.y >= 2 and minp.y <= 0 then
355 -- Generate papyrus
356 local perlin1 = minetest.get_perlin(354, 3, 0.7, 100)
357 -- Assume X and Z lengths are equal
358 local divlen = 8
359 local divs = (maxp.x-minp.x)/divlen+1;
360 for divx=0,divs-1 do
361 for divz=0,divs-1 do
362 local x0 = minp.x + math.floor((divx+0)*divlen)
363 local z0 = minp.z + math.floor((divz+0)*divlen)
364 local x1 = minp.x + math.floor((divx+1)*divlen)
365 local z1 = minp.z + math.floor((divz+1)*divlen)
366 -- Determine papyrus amount from perlin noise
367 local papyrus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 45 - 20)
368 -- Find random positions for papyrus based on this random
369 local pr = PseudoRandom(seed+1)
370 for i=0,papyrus_amount do
371 local x = pr:next(x0, x1)
372 local z = pr:next(z0, z1)
373 if minetest.get_node({x=x,y=1,z=z}).name == "default:dirt_with_grass" and
374 minetest.find_node_near({x=x,y=1,z=z}, 1, "default:water_source") then
375 default.make_papyrus({x=x,y=2,z=z}, pr:next(2, 4))
380 -- Generate cactuses
381 local perlin1 = minetest.get_perlin(230, 3, 0.6, 100)
382 -- Assume X and Z lengths are equal
383 local divlen = 16
384 local divs = (maxp.x-minp.x)/divlen+1;
385 for divx=0,divs-1 do
386 for divz=0,divs-1 do
387 local x0 = minp.x + math.floor((divx+0)*divlen)
388 local z0 = minp.z + math.floor((divz+0)*divlen)
389 local x1 = minp.x + math.floor((divx+1)*divlen)
390 local z1 = minp.z + math.floor((divz+1)*divlen)
391 -- Determine cactus amount from perlin noise
392 local cactus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 6 - 3)
393 -- Find random positions for cactus based on this random
394 local pr = PseudoRandom(seed+1)
395 for i=0,cactus_amount do
396 local x = pr:next(x0, x1)
397 local z = pr:next(z0, z1)
398 -- Find ground level (0...15)
399 local ground_y = nil
400 for y=30,0,-1 do
401 if minetest.get_node({x=x,y=y,z=z}).name ~= "air" then
402 ground_y = y
403 break
406 -- If desert sand, make cactus
407 if ground_y and minetest.get_node({x=x,y=ground_y,z=z}).name == "default:desert_sand" then
408 default.make_cactus({x=x,y=ground_y+1,z=z}, pr:next(3, 4))
413 -- Generate grass
414 local perlin1 = minetest.get_perlin(329, 3, 0.6, 100)
415 -- Assume X and Z lengths are equal
416 local divlen = 16
417 local divs = (maxp.x-minp.x)/divlen+1;
418 for divx=0,divs-1 do
419 for divz=0,divs-1 do
420 local x0 = minp.x + math.floor((divx+0)*divlen)
421 local z0 = minp.z + math.floor((divz+0)*divlen)
422 local x1 = minp.x + math.floor((divx+1)*divlen)
423 local z1 = minp.z + math.floor((divz+1)*divlen)
424 -- Determine grass amount from perlin noise
425 local grass_amount = math.floor(perlin1:get2d({x=x0, y=z0}) ^ 3 * 9)
426 -- Find random positions for grass based on this random
427 local pr = PseudoRandom(seed+1)
428 for i=0,grass_amount do
429 local x = pr:next(x0, x1)
430 local z = pr:next(z0, z1)
431 -- Find ground level (0...15)
432 local ground_y = nil
433 for y=30,0,-1 do
434 if minetest.get_node({x=x,y=y,z=z}).name ~= "air" then
435 ground_y = y
436 break
440 if ground_y then
441 local p = {x=x,y=ground_y+1,z=z}
442 local nn = minetest.get_node(p).name
443 -- Check if the node can be replaced
444 if minetest.registered_nodes[nn] and
445 minetest.registered_nodes[nn].buildable_to then
446 nn = minetest.get_node({x=x,y=ground_y,z=z}).name
447 -- If desert sand, add dry shrub
448 if nn == "default:desert_sand" then
449 minetest.set_node(p,{name="default:dry_shrub"})
451 -- If dirt with grass, add grass
452 elseif nn == "default:dirt_with_grass" then
453 minetest.set_node(p,{name="default:grass_"..pr:next(1, 5)})
463 -- Generate nyan cats
464 generate_nyancats(seed, minp, maxp)
465 end)