Generate only desert seeds for some structs and lots of debugging glass blocks in the sky

This commit is contained in:
kay27 2022-01-10 19:35:04 +04:00
parent 667ebf1385
commit 16116df4c6
1 changed files with 212 additions and 68 deletions

View File

@ -7,26 +7,28 @@ local DIVLEN = 5
local V6 = mcl_mapgen.v6
local math_min, math_max = math.min, math.max
local math_floor = math.floor
local math_floor, math_ceil = math.floor, math.ceil
local minetest_get_node = minetest.get_node
local minetest_get_mapgen_object = minetest.get_mapgen_object
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
local minetest_get_item_group = minetest.get_item_group
local perlin_structures
local function determine_ground_level(p, vm_context)
local emax = vm_context.emax
local emax_y = emax.y
local y = math_min(OVERWORLD_STRUCT_MAX, emax_y)
if y < emax_y then
local maxp = vm_context.maxp
local maxp_y = maxp.y
local y = math_min(OVERWORLD_STRUCT_MAX, maxp_y)
if y < maxp_y then
y = y + 1
end
p.y = y
local checknode = minetest_get_node(p)
if checknode.name ~= "air" then
return
end
for y = y - 1, math_max(OVERWORLD_STRUCT_MIN, vm_context.emin.y), -1 do
local nn = checknode.name
if nn ~= "air" and minetest_get_item_group(nn, "attached_node") == 0 and minetest_get_item_group(nn, "deco_block") == 0 then return end
for y = y - 1, math_max(OVERWORLD_STRUCT_MIN, vm_context.minp.y), -1 do
p.y = y
local checknode = minetest_get_node(p)
if checknode then
@ -57,53 +59,136 @@ end
-- (in on_generated callback) and returns a biomemap index)
-- Inverse function of biomemap_to_xz
local function xz_to_biomemap_index(x, z, minp, maxp)
local xwidth = maxp.x - minp.x + 1
local zwidth = maxp.z - minp.z + 1
local minix = x % xwidth
local miniz = z % zwidth
return (minix + miniz * zwidth) + 1
local zstride = maxp.z - minp.z + 1
return (z - minp.z) * zstride + (x - minp.x) + 1
end
local chunk_has_desert_struct
local chunk_has_igloo
--local chunk_has_desert_struct
--local chunk_has_desert_temple
--local chunk_has_igloo
local function spawn_desert_temples_and_desert_wells(p, nn, pr, vm_context)
if chunk_has_desert_struct or p.y < 5 then return end
minetest.register_node("mcl_mapgen_core:desert_temple", {
-- drawtype="airlike",
tiles = {"mcl_core_stonebrick_carved.png"},
groups = {
struct = 1,
not_in_creative_inventory = 1,
},
})
local octaves = 3
local persistence = 0.6
local offset = 0
local scale = 1
local max_noise = 0
for i = 1, octaves do
local noise = 1 * (persistence ^ (i - 1))
max_noise = max_noise + noise
end
max_noise = max_noise * octaves
max_noise = offset + scale * max_noise
--[[function structures.register_structure(
name, -- "desert_temple"
place_on, -- {"mcl_core:sand", "mcl_core:sandstone"}
flags, -- "all_floors"
]]
minetest.register_decoration({
decoration = "mcl_mapgen_core:desert_temple",
deco_type = "simple",
place_on = {"mcl_core:sand", "mcl_core:sandstone"},
flags = "all_floors",
--[[ noise_params = {
offset = offset,
scale = scale,
spread = {
x = 1,
y = 1,
z = 1,
},
seed = 329,
octaves = octaves,
persistence = persistence,
lacunarity = 2.0,
flags = "eased",
},
noise_threshold = 1000,-- * 0.9,
]]
fill_ratio = 0.001,
y_min = 5,
y_max = mcl_mapgen.overworld.max,
height = 1,
biomes = {
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"Desert",
"Desert_ocean",
"ExtremeHills_beach",
"FlowerForest_beach",
"Forest_beach",
"MesaBryce_sandlevel",
"MesaPlateauF_sandlevel",
"MesaPlateauFM_sandlevel",
"Savanna",
"Savanna_beach",
"StoneBeach",
"StoneBeach_ocean",
"Taiga_beach",
},
})
--minetest.register_lbm(
-- name = "mcl_mapgen_core:process_struct_seed",
-- nodenames = {
-- "group:struct",
-- }
-- run_at_everly_load = true,
-- action = function(pos, node)
-- end,
--)
local function spawn_desert_temple(p, nn, pr, vm_context)
if p.y < 5 then return end
if nn ~= "mcl_core:sand" and nn ~= "mcl_core:sandstone" then return end
-- Spawn desert temple
if pr:next(1,12000) == 1 then
mcl_structures.call_struct(p, "desert_temple", nil, pr)
chunk_has_desert_struct = true
return true
end
-- Spawn desert well
local desert_well_prob = minecraft_chunk_probability(1000, vm_context.minp, vm_context.maxp)
if pr:next(1, desert_well_prob) ~= 1 then return end
-- Check surface
local surface = minetest_find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand")
if #surface < 25 then return end
mcl_structures.call_struct(p, "desert_well", nil, pr)
chunk_has_desert_struct = true
-- if pr:next(1,12000) ~= 1 then return end
mcl_structures.call_struct(p, "desert_temple", nil, pr)
return true
end
local function spawn_igloos(p, nn, pr)
if chunk_has_igloo then return end
if nn ~= "mcl_core:snowblock" and nn ~= "mcl_core:snow" and minetest.get_item_group(nn, "grass_block_snow") ~= 1 then return end
if pr:next(1, 4400) ~= 1 then return end
local function spawn_desert_well(p, nn, pr, vm_context)
if p.y < 5 then return end
if nn ~= "mcl_core:sand" and nn ~= "mcl_core:sandstone" then return end
local desert_well_prob = minecraft_chunk_probability(1000, vm_context.minp, vm_context.maxp)
-- if pr:next(1, desert_well_prob) ~= 1 then return end
local surface = minetest_find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand")
if #surface < 25 then return end
mcl_structures.call_struct(p, "desert_well", nil, pr)
return true
end
local function spawn_igloo(p, nn, pr, vm_context)
if nn ~= "mcl_core:snowblock" and nn ~= "mcl_core:snow" and minetest_get_item_group(nn, "grass_block_snow") ~= 1 then return end
-- if pr:next(1, 4400) ~= 1 then return end
-- Check surface
local floor = {x=p.x+9, y=p.y-1, z=p.z+9}
local surface = minetest_find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock")
local surface2 = minetest_find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow")
if #surface + #surface2 < 63 then return end
local surface = minetest_find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"})
if #surface < 63 then return end
mcl_structures.call_struct(p, "igloo", nil, pr)
chunk_has_igloo = true
-- chunk_has_igloo = true
return true
end
local function spawn_fossil(p, nn, pr, vm_context)
if chunk_has_desert_struct or p.y > 4 then return end
-- if chunk_has_desert_temple or p.y < 4 then return end
if p.y < 4 then return end
if nn ~= "mcl_core:sandstone" and nn ~= "mcl_core:sand" then return end
local fossil_prob = minecraft_chunk_probability(64, vm_context.minp, vm_context.maxp)
if pr:next(1, fossil_prob) ~= 1 then return end
@ -134,10 +219,12 @@ local witch_hut_offsets = {
}
local function spawn_witch_hut(p, nn, pr, vm_context)
if p.y <= 1 or nn ~= "mcl_core:dirt" then return end
minetest.log("warning", "p="..minetest.pos_to_string(p)..", nn="..nn)
-- if p.y > 1 or minetest_get_item_group(nn, "dirt") == 0 then return end
local minp, maxp = vm_context.minp, vm_context.maxp
local prob = minecraft_chunk_probability(48, minp, maxp)
if pr:next(1, prob) ~= 1 then return end
minetest.log("warning", "prob="..tostring(prob))
-- if pr:next(1, prob) ~= 1 then return end
-- Where do witches live?
if V6 then
@ -147,13 +234,20 @@ local function spawn_witch_hut(p, nn, pr, vm_context)
-- Other mapgens: In swampland biome
local biomemap = vm_context.biomemap
if not biomemap then
vm_context.biomemap = vm_context.biomemap or minetest_get_mapgen_object('biomemap')
vm_context.biomemap = minetest_get_mapgen_object('biomemap')
biomemap = vm_context.biomemap
end
-- minetest.chat_send_all(minetest.serialize(biomemap))
local swampland = minetest.get_biome_id("Swampland")
local swampland_shore = minetest.get_biome_id("Swampland_shore")
local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp)
if biomemap[bi] ~= swampland and biomemap[bi] ~= swampland_shore then return end
local bi = xz_to_biomemap_index(p.x, p.z, vm_context.minp, vm_context.maxp)
if (biomemap[bi] == swampland) then
minetest.chat_send_all('swampland')
end
if (biomemap[bi] == swampland_shore) then
minetest.chat_send_all('swampland_shore')
end
-- if biomemap[bi] ~= swampland and biomemap[bi] ~= swampland_shore then return end
end
local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270"
@ -237,7 +331,8 @@ end
local function spawn_spikes_in_v6(p, nn, pr)
-- In other mapgens, ice spikes are generated as decorations.
if chunk_has_igloo or nn ~= "mcl_core:snowblock" then return end
-- if chunk_has_igloo or nn ~= "mcl_core:snowblock" then return end
if nn ~= "mcl_core:snowblock" then return end
local spike = pr:next(1,58000)
if spike < 3 then
return spawn_ice_spike_large(p, pr)
@ -247,31 +342,77 @@ local function spawn_spikes_in_v6(p, nn, pr)
end
local function generate_structures(vm_context)
local pr = PcgRandom(vm_context.blockseed)
perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100)
chunk_has_desert_struct = false
chunk_has_igloo = false
local levels = {
[-9] = "black",
[-8] = "brown",
[-7] = "brown",
[-6] = "gray",
[-5] = "gray",
[-4] = "red",
[-3] = "orange",
[-2] = "purple",
[-1] = "magenta",
[0] = "pink",
[1] = "yellow",
[2] = "green",
[3] = "lime",
[4] = "blue",
[5] = "cyan",
[6] = "light_blue",
[7] = "silver",
[8] = "silver",
[9] = "white",
}
-- local pr = PcgRandom(vm_context.blockseed)
local pr = PcgRandom(vm_context.chunkseed)
-- chunk_has_desert_struct = false
-- chunk_has_desert_temple = false
-- chunk_has_igloo = false
local minp, maxp = vm_context.minp, vm_context.maxp
perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100)
-- Assume X and Z lengths are equal
local DIVLEN = 5
for x0 = minp.x, maxp.x, DIVLEN do for z0 = minp.z, maxp.z, DIVLEN do
-- Determine amount from perlin noise
local amount = math_floor(perlin_structures:get_2d({x=x0, y=z0}) * 9)
local noise = perlin_structures:get_2d({x=x0, y=z0})
local amount
if noise < 0 then
amount = math_ceil(noise * 9)
else
amount = math_floor(noise * 9)
end
-- local amount = math_floor(perlin_structures:get_2d({x=x0, y=z0}) * 9)
local y1 = maxp.y - 9 + amount
for x1 = x0, x0 + DIVLEN - 1, 1 do for z1 = z0, z0 + DIVLEN - 1, 1 do
if not levels[amount] then
minetest.log("ERROR",tostring(amount))
else
minetest.set_node({x=x1, y=y1, z=z1}, {name = "mcl_core:glass_"..levels[amount]})
end
end end
-- Find random positions based on this random
local p, ground_y, nn
for i=0, amount do
p = {x = pr:next(x0, x0 + DIVLEN - 1), y = 0, z = pr:next(z0, z0 + DIVLEN - 1)}
for i = 0, 24 do
--for i=0, amount do
-- p = {x = pr:next(x0, x0 + DIVLEN - 1), y = 0, z = pr:next(z0, z0 + DIVLEN - 1)}
p = {x = x0 + i % 5, z = z0 + math_floor(i/5)}
p, ground_y, nn = determine_ground_level(p, vm_context)
if ground_y then
p.y = ground_y + 1
local nn0 = minetest.get_node(p).name
-- Check if the node can be replaced
if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then
if not spawn_desert_temples_and_desert_wells(p, nn, pr, vm_context) then
spawn_igloos(p, nn, pr, vm_context)
end
spawn_fossil(p, nn, pr, vm_context)
spawn_witch_hut(p, nn, pr, vm_context)
--spawn_desert_temple(p, nn, pr, vm_context)
--spawn_desert_well(p, nn, pr, vm_context)
--spawn_igloo(p, nn, pr, vm_context)
--spawn_fossil(p, nn, pr, vm_context)
--spawn_witch_hut(p, nn, pr, vm_context)
if V6 then
spawn_spikes_in_v6(p, nn, pr, vm_context)
end
@ -301,15 +442,18 @@ local function generate_end_structures(vm_context)
end
if not mcl_mapgen.singlenode then
mcl_mapgen.register_on_generated(function(vm_context)
local minp, maxp = vm_context.minp, vm_context.maxp
mcl_mapgen.register_mapgen(function(minp, maxp, seed, vm_context)
-- mcl_mapgen.register_on_generated(function(vm_context)
-- local minp, maxp = vm_context.minp, vm_context.maxp
local minp, maxp = minp, maxp
local minp_y, maxp_y = minp.y, maxp.y
if maxp_y >= OVERWORLD_STRUCT_MIN and minp_y <= OVERWORLD_STRUCT_MAX then
return generate_structures(vm_context)
generate_structures(vm_context)
-- if maxp_y >= OVERWORLD_STRUCT_MIN and minp_y <= OVERWORLD_STRUCT_MAX then
-- return generate_structures(vm_context)
-- End exit portal
elseif maxp_y >= END_STRUCT_MIN and minp_y <= END_STRUCT_MAX then
return generate_end_structures(vm_context)
end
return vm_context
-- elseif maxp_y >= END_STRUCT_MIN and minp_y <= END_STRUCT_MAX then
-- return generate_end_structures(vm_context)
-- end
-- return vm_context
end)
end