mirror of
https://github.com/luanti-org/minetest_game.git
synced 2025-03-20 06:41:22 +00:00
E.g. in stone where it had already been spawned in maps prior to this change, in structures made with the old block, etc. Mese ore (of a sort), as default:stone_with_mese, is generated now instead of default:mese (which is not generated at all now). The new default:mese_block is substituted in place of default:mese by way of an alias. Crystals still come from Mese Crystals in Stone, while digging buried Mese Blocks returns exactly those (the same as can be crafted from 9 crystals). If necessary, they can be split up into Mese Crystals again via the existing crafting recipe. This alters the value of the various Mese items a little, but avoids breaking old structures that were made of mese. The original default:mese, if needed, can be obtained by crafting two Mese Crystals, which yields two of the old Mese object. Two of these can be crafted back into two Crystals if needed.
292 lines
10 KiB
Lua
292 lines
10 KiB
Lua
-- minetest/default/mapgen.lua
|
|
|
|
--
|
|
-- Aliases for map generator outputs
|
|
--
|
|
|
|
minetest.register_alias("mapgen_air", "air")
|
|
minetest.register_alias("mapgen_stone", "default:stone")
|
|
minetest.register_alias("mapgen_tree", "default:tree")
|
|
minetest.register_alias("mapgen_leaves", "default:leaves")
|
|
minetest.register_alias("mapgen_apple", "default:apple")
|
|
minetest.register_alias("mapgen_water_source", "default:water_source")
|
|
minetest.register_alias("mapgen_dirt", "default:dirt")
|
|
minetest.register_alias("mapgen_sand", "default:sand")
|
|
minetest.register_alias("mapgen_gravel", "default:gravel")
|
|
minetest.register_alias("mapgen_clay", "default:clay")
|
|
minetest.register_alias("mapgen_lava_source", "default:lava_source")
|
|
minetest.register_alias("mapgen_cobble", "default:cobble")
|
|
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
|
|
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
|
|
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
|
|
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
|
|
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
|
|
minetest.register_alias("mapgen_mese", "default:stone_with_mese")
|
|
minetest.register_alias("mapgen_desert_sand", "default:desert_sand")
|
|
minetest.register_alias("mapgen_desert_stone", "default:desert_stone")
|
|
|
|
--
|
|
-- Ore generation
|
|
--
|
|
|
|
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, chunk_size, ore_per_chunk, height_min, height_max)
|
|
if maxp.y < height_min or minp.y > height_max then
|
|
return
|
|
end
|
|
local y_min = math.max(minp.y, height_min)
|
|
local y_max = math.min(maxp.y, height_max)
|
|
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
|
|
local pr = PseudoRandom(seed)
|
|
local num_chunks = math.floor(chunks_per_volume * volume)
|
|
local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
|
|
--print("generate_ore num_chunks: "..dump(num_chunks))
|
|
for i=1,num_chunks do
|
|
local y0 = pr:next(y_min, y_max-chunk_size+1)
|
|
if y0 >= height_min and y0 <= height_max then
|
|
local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
|
|
local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
|
|
local p0 = {x=x0, y=y0, z=z0}
|
|
for x1=0,chunk_size-1 do
|
|
for y1=0,chunk_size-1 do
|
|
for z1=0,chunk_size-1 do
|
|
if pr:next(1,inverse_chance) == 1 then
|
|
local x2 = x0+x1
|
|
local y2 = y0+y1
|
|
local z2 = z0+z1
|
|
local p2 = {x=x2, y=y2, z=z2}
|
|
if minetest.env:get_node(p2).name == wherein then
|
|
minetest.env:set_node(p2, {name=name})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
--print("generate_ore done")
|
|
end
|
|
|
|
function default.make_papyrus(pos, size)
|
|
for y=0,size-1 do
|
|
local p = {x=pos.x, y=pos.y+y, z=pos.z}
|
|
local nn = minetest.env:get_node(p).name
|
|
if minetest.registered_nodes[nn] and
|
|
minetest.registered_nodes[nn].buildable_to then
|
|
minetest.env:set_node(p, {name="default:papyrus"})
|
|
else
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
function default.make_cactus(pos, size)
|
|
for y=0,size-1 do
|
|
local p = {x=pos.x, y=pos.y+y, z=pos.z}
|
|
local nn = minetest.env:get_node(p).name
|
|
if minetest.registered_nodes[nn] and
|
|
minetest.registered_nodes[nn].buildable_to then
|
|
minetest.env:set_node(p, {name="default:cactus"})
|
|
else
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
-- facedir: 0/1/2/3 (head node facedir value)
|
|
-- length: length of rainbow tail
|
|
function default.make_nyancat(pos, facedir, length)
|
|
local tailvec = {x=0, y=0, z=0}
|
|
if facedir == 0 then
|
|
tailvec.z = 1
|
|
elseif facedir == 1 then
|
|
tailvec.x = 1
|
|
elseif facedir == 2 then
|
|
tailvec.z = -1
|
|
elseif facedir == 3 then
|
|
tailvec.x = -1
|
|
else
|
|
print("default.make_nyancat(): Invalid facedir: "+dump(facedir))
|
|
facedir = 0
|
|
tailvec.z = 1
|
|
end
|
|
local p = {x=pos.x, y=pos.y, z=pos.z}
|
|
minetest.env:set_node(p, {name="default:nyancat", param2=facedir})
|
|
for i=1,length do
|
|
p.x = p.x + tailvec.x
|
|
p.z = p.z + tailvec.z
|
|
minetest.env:set_node(p, {name="default:nyancat_rainbow"})
|
|
end
|
|
end
|
|
|
|
function generate_nyancats(seed, minp, maxp)
|
|
local height_min = -31000
|
|
local height_max = -32
|
|
if maxp.y < height_min or minp.y > height_max then
|
|
return
|
|
end
|
|
local y_min = math.max(minp.y, height_min)
|
|
local y_max = math.min(maxp.y, height_max)
|
|
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
|
|
local pr = PseudoRandom(seed + 9324342)
|
|
local max_num_nyancats = math.floor(volume / (16*16*16))
|
|
for i=1,max_num_nyancats do
|
|
if pr:next(0, 1000) == 0 then
|
|
local x0 = pr:next(minp.x, maxp.x)
|
|
local y0 = pr:next(minp.y, maxp.y)
|
|
local z0 = pr:next(minp.z, maxp.z)
|
|
local p0 = {x=x0, y=y0, z=z0}
|
|
default.make_nyancat(p0, pr:next(0,3), pr:next(3,15))
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
-- Generate regular ores
|
|
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed+0, 1/8/8/8, 3, 8, -31000, 64)
|
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+1, 1/12/12/12, 2, 3, -15, 2)
|
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+2, 1/9/9/9, 3, 5, -63, -16)
|
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+3, 1/7/7/7, 3, 5, -31000, -64)
|
|
generate_ore("default:stone_with_mese", "default:stone", minp, maxp, seed+4, 1/16/16/16, 2, 3, -127, -64)
|
|
generate_ore("default:stone_with_mese", "default:stone", minp, maxp, seed+5, 1/9/9/9, 3, 5, -31000,-128)
|
|
|
|
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed+7, 1/24/24/24, 6,27, -31000, 0)
|
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+6, 1/24/24/24, 6,27, -31000, -64)
|
|
|
|
if maxp.y >= 2 and minp.y <= 0 then
|
|
-- Generate clay
|
|
-- Assume X and Z lengths are equal
|
|
local divlen = 4
|
|
local divs = (maxp.x-minp.x)/divlen+1;
|
|
for divx=0+1,divs-1-1 do
|
|
for divz=0+1,divs-1-1 do
|
|
local cx = minp.x + math.floor((divx+0.5)*divlen)
|
|
local cz = minp.z + math.floor((divz+0.5)*divlen)
|
|
if minetest.env:get_node({x=cx,y=1,z=cz}).name == "default:water_source" and
|
|
minetest.env:get_node({x=cx,y=0,z=cz}).name == "default:sand" then
|
|
local is_shallow = true
|
|
local num_water_around = 0
|
|
if minetest.env:get_node({x=cx-divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
|
num_water_around = num_water_around + 1 end
|
|
if minetest.env:get_node({x=cx+divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
|
num_water_around = num_water_around + 1 end
|
|
if minetest.env:get_node({x=cx+0,y=1,z=cz-divlen*2}).name == "default:water_source" then
|
|
num_water_around = num_water_around + 1 end
|
|
if minetest.env:get_node({x=cx+0,y=1,z=cz+divlen*2}).name == "default:water_source" then
|
|
num_water_around = num_water_around + 1 end
|
|
if num_water_around >= 2 then
|
|
is_shallow = false
|
|
end
|
|
if is_shallow then
|
|
for x1=-divlen,divlen do
|
|
for z1=-divlen,divlen do
|
|
if minetest.env:get_node({x=cx+x1,y=0,z=cz+z1}).name == "default:sand" then
|
|
minetest.env:set_node({x=cx+x1,y=0,z=cz+z1}, {name="default:clay"})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Generate papyrus
|
|
local perlin1 = minetest.env:get_perlin(354, 3, 0.7, 100)
|
|
-- Assume X and Z lengths are equal
|
|
local divlen = 8
|
|
local divs = (maxp.x-minp.x)/divlen+1;
|
|
for divx=0,divs-1 do
|
|
for divz=0,divs-1 do
|
|
local x0 = minp.x + math.floor((divx+0)*divlen)
|
|
local z0 = minp.z + math.floor((divz+0)*divlen)
|
|
local x1 = minp.x + math.floor((divx+1)*divlen)
|
|
local z1 = minp.z + math.floor((divz+1)*divlen)
|
|
-- Determine papyrus amount from perlin noise
|
|
local papyrus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 45 - 20)
|
|
-- Find random positions for papyrus based on this random
|
|
local pr = PseudoRandom(seed+1)
|
|
for i=0,papyrus_amount do
|
|
local x = pr:next(x0, x1)
|
|
local z = pr:next(z0, z1)
|
|
if minetest.env:get_node({x=x,y=1,z=z}).name == "default:dirt_with_grass" and
|
|
minetest.env:find_node_near({x=x,y=1,z=z}, 1, "default:water_source") then
|
|
default.make_papyrus({x=x,y=2,z=z}, pr:next(2, 4))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Generate cactuses
|
|
local perlin1 = minetest.env:get_perlin(230, 3, 0.6, 100)
|
|
-- Assume X and Z lengths are equal
|
|
local divlen = 16
|
|
local divs = (maxp.x-minp.x)/divlen+1;
|
|
for divx=0,divs-1 do
|
|
for divz=0,divs-1 do
|
|
local x0 = minp.x + math.floor((divx+0)*divlen)
|
|
local z0 = minp.z + math.floor((divz+0)*divlen)
|
|
local x1 = minp.x + math.floor((divx+1)*divlen)
|
|
local z1 = minp.z + math.floor((divz+1)*divlen)
|
|
-- Determine cactus amount from perlin noise
|
|
local cactus_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 6 - 3)
|
|
-- Find random positions for cactus based on this random
|
|
local pr = PseudoRandom(seed+1)
|
|
for i=0,cactus_amount do
|
|
local x = pr:next(x0, x1)
|
|
local z = pr:next(z0, z1)
|
|
-- Find ground level (0...15)
|
|
local ground_y = nil
|
|
for y=30,0,-1 do
|
|
if minetest.env:get_node({x=x,y=y,z=z}).name ~= "air" then
|
|
ground_y = y
|
|
break
|
|
end
|
|
end
|
|
-- If desert sand, make cactus
|
|
if ground_y and minetest.env:get_node({x=x,y=ground_y,z=z}).name == "default:desert_sand" then
|
|
default.make_cactus({x=x,y=ground_y+1,z=z}, pr:next(3, 4))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Generate dry shrubs
|
|
local perlin1 = minetest.env:get_perlin(329, 3, 0.6, 100)
|
|
-- Assume X and Z lengths are equal
|
|
local divlen = 16
|
|
local divs = (maxp.x-minp.x)/divlen+1;
|
|
for divx=0,divs-1 do
|
|
for divz=0,divs-1 do
|
|
local x0 = minp.x + math.floor((divx+0)*divlen)
|
|
local z0 = minp.z + math.floor((divz+0)*divlen)
|
|
local x1 = minp.x + math.floor((divx+1)*divlen)
|
|
local z1 = minp.z + math.floor((divz+1)*divlen)
|
|
-- Determine dry shrubs amount from perlin noise
|
|
local shrub_amount = math.floor(perlin1:get2d({x=x0, y=z0}) * 5 + 0)
|
|
-- Find random positions for dry shrubs based on this random
|
|
local pr = PseudoRandom(seed+1)
|
|
for i=0,shrub_amount do
|
|
local x = pr:next(x0, x1)
|
|
local z = pr:next(z0, z1)
|
|
-- Find ground level (0...15)
|
|
local ground_y = nil
|
|
for y=30,0,-1 do
|
|
if minetest.env:get_node({x=x,y=y,z=z}).name ~= "air" then
|
|
ground_y = y
|
|
break
|
|
end
|
|
end
|
|
-- If desert sand, make dry shrub
|
|
if ground_y and minetest.env:get_node({x=x,y=ground_y,z=z}).name == "default:desert_sand" then
|
|
local p = {x=x,y=ground_y+1,z=z}
|
|
local nn = minetest.env:get_node(p).name
|
|
if minetest.registered_nodes[nn] and
|
|
minetest.registered_nodes[nn].buildable_to then
|
|
minetest.env:set_node(p, {name="default:dry_shrub"})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Generate nyan cats
|
|
generate_nyancats(seed, minp, maxp)
|
|
end)
|
|
|