Add old structures to new mod

This commit is contained in:
kay27 2022-01-18 19:17:20 +04:00
parent ae6d9e44b0
commit da606acfd1
10 changed files with 228 additions and 120 deletions

View File

@ -4,15 +4,22 @@ local c_clay = minetest.get_content_id("mcl_core:clay")
local perlin_clay
mcl_mapgen.register_mapgen_lvm(function(c)
local minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used = c.minp, c.maxp, c.chunkseed, c.data, c.area, c.write or false
-- TODO: Make clay generation reproducible for same seed.
if maxp.y < -5 or minp.y > 0 then
return c
end
c.vm = c.vm or mcl_mapgen.get_voxel_manip(c)
local math_max = math.max
local math_min = math.min
local math_floor = math.floor
local math_abs = math.abs
local offset = math_floor(mcl_mapgen.BS / 2)
local minetest_get_item_group = minetest.get_item_group
local minetest_get_name_from_content_id = minetest.get_name_from_content_id
minetest.log("warning", "CLAY!")
mcl_mapgen.register_mapgen_block_lvm(function(c)
local minp, maxp, blockseed, voxelmanip_data, voxelmanip_area = c.minp, c.maxp, c.blockseed, c.data, c.area
local max_y = maxp.y
if max_y < -7 then return end
local min_y = minp.y
if min_y > 0 then return end
c.vm = c.vm or mcl_mapgen.get_voxel_manip(c)
local pr = PseudoRandom(blockseed)
@ -25,40 +32,32 @@ mcl_mapgen.register_mapgen_lvm(function(c)
persist = 0.0
})
for y=math.max(minp.y, 0), math.min(maxp.y, -8), -1 do
for y = math_max(min_y, -8), math_min(max_y, 0) do
-- Assume X and Z lengths are equal
local divlen = 4
local divs = (maxp.x-minp.x)/divlen+1;
for divx=0+1,divs-2 do
for divz=0+1,divs-2 do
local x = minp.x + offset + pr:next(-2, 2)
local z = minp.z + offset + pr:next(-2, 2)
if perlin_clay:get_3d({x = x, y = y, z = z}) + pr:next(1, 20) > 19 then
-- Get position and shift it a bit randomly so the clay do not obviously appear in a grid
local cx = minp.x + math.floor((divx+0.5)*divlen) + pr:next(-1,1)
local cz = minp.z + math.floor((divz+0.5)*divlen) + pr:next(-1,1)
local water_pos = voxelmanip_area:index(cx, y+1, cz)
local waternode = voxelmanip_data[water_pos]
local surface_pos = voxelmanip_area:index(cx, y, cz)
local surfacenode = voxelmanip_data[surface_pos]
local genrnd = pr:next(1, 20)
if genrnd == 1 and perlin_clay:get_3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and
(surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then
local diamondsize = pr:next(1, 3)
for x1 = -diamondsize, diamondsize do
for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do
local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1)
local claycandidate = voxelmanip_data[ccpos]
if voxelmanip_data[ccpos] == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(claycandidate), "sand") == 1 then
voxelmanip_data[ccpos] = c_clay
minetest.log("warning", "CLAY! "..minetest.pos_to_string({x=cx+x1,y=y,z=cz+z1}))
lvm_used = true
local water_pos = voxelmanip_area:index(x, y + 1, z)
local water_node = voxelmanip_data[water_pos]
if water_node == c_water or water_node == c_clay then
local surface_pos = voxelmanip_area:index(x, y, z)
local surface_node = voxelmanip_data[surface_pos]
if (surface_node == c_dirt or surface_node == c_clay or minetest_get_item_group(minetest_get_name_from_content_id(surface_node), "sand") == 1) then
local diamondsize = pr:next(1, 3)
for x1 = -diamondsize, diamondsize do
local abs_x1 = math_abs(x1)
for z1 = -(diamondsize - abs_x1), diamondsize - abs_x1 do
local ccpos = voxelmanip_area:index(x + x1, y, z + z1)
local claycandidate = voxelmanip_data[ccpos]
if voxelmanip_data[ccpos] == c_dirt or minetest_get_item_group(minetest_get_name_from_content_id(claycandidate), "sand") == 1 then
voxelmanip_data[ccpos] = c_clay
c.write = true
end
end
end
end
end
end
end
end
end
c.write = lvm_used
return c
end)

View File

@ -81,25 +81,6 @@ end
max_noise = max_noise * octaves
max_noise = offset + scale * max_noise
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
-- if pr:next(1,12000) ~= 1 then return end
mcl_structures.call_struct(p, "desert_temple", nil, pr)
return true
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
@ -112,23 +93,6 @@ local function spawn_igloo(p, nn, pr, vm_context)
return true
end
local function spawn_fossil(p, nn, pr, vm_context)
-- 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
-- Spawn fossil below desert surface between layers 40 and 49
local p1 = {x=p.x, y=pr:next(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z}
-- Very rough check of the environment (we expect to have enough stonelike nodes).
-- Fossils may still appear partially exposed in caves, but this is O.K.
local p2 = vector.add(p1, 4)
local nodes = minetest_find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"})
if #nodes < 100 then return end
-- >= 80%
mcl_structures.call_struct(p1, "fossil", nil, pr)
end
local witch_hut_offsets = {
["0"] = {
{x=1, y=0, z=1}, {x=1, y=0, z=5}, {x=6, y=0, z=1}, {x=6, y=0, z=5},

View File

@ -4,6 +4,7 @@ local modpath = minetest.get_modpath(modname)
local chance_per_chunk = 11
local noise_multiplier = 1
local random_offset = 999
local scanning_ratio = 0.00003
local struct_threshold = chance_per_chunk - 1
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
@ -128,7 +129,7 @@ mcl_structures.register_structure({
deco_type = "simple",
place_on = node_list,
flags = "all_floors",
fill_ratio = 0.00003,
fill_ratio = scanning_ratio,
y_min = 3,
y_max = mcl_mapgen.overworld.max,
height = 1,

View File

@ -0,0 +1,94 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local chance_per_chunk = 60
local noise_multiplier = 1
local random_offset = 999
local scanning_ratio = 0.00001
local struct_threshold = chance_per_chunk - 1
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
local node_list = {"mcl_core:sand", "mcl_core:sandstone", "mcl_core:redsand", "mcl_colorblocks:hardened_clay_orange"}
local schematic_file = modpath .. "/schematics/mcl_structures_desert_well.mts"
local well_schematic_lua = minetest.serialize_schematic(schematic_file, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic"
local well_schematic = loadstring(well_schematic_lua)()
local red_well_schematic_lua = minetest.serialize_schematic(schematic_file, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic"
red_well_schematic_lua = red_well_schematic_lua:gsub("mcl_core:sand", "mcl_core:redsand")
red_well_schematic_lua = red_well_schematic_lua:gsub("mcl_stairs:slab_sandstone", "mcl_stairs:slab_redsandstone")
local red_well_schematic = loadstring(red_well_schematic_lua)()
local function place(pos, rotation, pr)
local pos_below = {x = pos.x, y = pos.y - 1, z = pos.z}
local pos_well = {x = pos.x, y = pos.y - 2, z = pos.z}
local node_below = minetest.get_node(pos_below)
local nn = node_below.name
if string.find(nn, "red") then
mcl_structures.place_schematic({pos = pos_well, rotaton = rotation, schematic = red_well_schematic, pr = pr})
else
mcl_structures.place_schematic({pos = pos_well, rotaton = rotation, schematic = well_schematic, pr = pr})
end
end
local function get_place_rank(pos)
local x, y, z = pos.x, pos.y - 1, pos.z
local p1 = {x = x , y = y, z = z }
local p2 = {x = x + 5, y = y, z = z + 5}
local post_pos_list_surface = #minetest.find_nodes_in_area(p1, p2, node_list, false)
local other_pos_list_surface = #minetest.find_nodes_in_area(p1, p2, "group:opaque", false)
return post_pos_list_surface * 5 + other_pos_list_surface
end
mcl_structures.register_structure({
name = "desert_well",
decoration = {
deco_type = "simple",
place_on = node_list,
flags = "all_floors",
fill_ratio = scanning_ratio,
y_min = -5,
y_max = mcl_mapgen.overworld.max,
height = 1,
biomes = not mcl_mapgen.v6 and {
"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",
},
},
on_finished_chunk = function(minp, maxp, seed, vm_context, pos_list)
local pr = PseudoRandom(seed + random_offset)
local random_number = pr:next(1, chance_per_chunk)
local noise = mcl_structures_get_perlin_noise_level(minp) * noise_multiplier
if (random_number + noise) < struct_threshold then return end
local pos = pos_list[1]
if #pos_list > 1 then
local count = get_place_rank(pos)
for i = 2, #pos_list do
local pos_i = pos_list[i]
local count_i = get_place_rank(pos_i)
if count_i > count then
count = count_i
pos = pos_i
end
end
end
local pr = PseudoRandom(vm_context.chunkseed)
place(pos, nil, pr)
end,
place_function = place,
})

View File

@ -0,0 +1,53 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local chance_per_block = mcl_structures.from_16x16_to_block_inverted_chance(64)
local noise_multiplier = 2
local random_offset = 5
local struct_threshold = chance_per_block - 1
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
local min_y = mcl_worlds.layer_to_y(40)
local max_y = mcl_worlds.layer_to_y(49)
local fossils = {
"mcl_structures_fossil_skull_1.mts", -- 4×5×5
"mcl_structures_fossil_skull_2.mts", -- 5×5×5
"mcl_structures_fossil_skull_3.mts", -- 5×5×7
"mcl_structures_fossil_skull_4.mts", -- 7×5×5
"mcl_structures_fossil_spine_1.mts", -- 3×3×13
"mcl_structures_fossil_spine_2.mts", -- 5×4×13
"mcl_structures_fossil_spine_3.mts", -- 7×4×13
"mcl_structures_fossil_spine_4.mts", -- 8×5×13
}
local nodes_for_fossil = {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}
function spawn_fossil(pos, rotation, pr, placer)
-- Generates one out of 8 possible fossil pieces
local def = {
pos = {x = pos.x, y = pos.y - 1, z = pos.z},
schematic = modpath .. "/schematics/" .. fossils[pr:next(1, #fossils)],
rotation = rotation,
pr = pr,
}
mcl_structures.place_schematic(def)
end
mcl_mapgen.register_mapgen_block(function(minp, maxp, seed)
local p1 = table.copy(minp)
local y1 = p1.y
if y1 > max_y then return end
local p2 = table.copy(maxp)
local y2 = p2.y
if y2 < min_y then return end
local pr = PseudoRandom(seed + random_offset)
local random_number = pr:next(1, chance_per_block)
p1.y = math.max(y1, min_y)
local noise = mcl_structures_get_perlin_noise_level(p1) * noise_multiplier
if (random_number + noise) < struct_threshold then return end
p2.y = math.min(y2, max_y)
local nodes = minetest_find_nodes_in_area(p1, p2, nodes_for_fossil, false)
if #nodes < 100 then return end
spawn_fossil(p1, nil, pr)
end, 1000)
mcl_structures.register_structure({name = 'fossil', place_function = spawn_fossil})

View File

@ -337,9 +337,7 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr, callback)
if not rotation then
rotation = "random"
end
if struct_style == "desert_well" then
return mcl_structures.generate_desert_well(pos, rotation)
elseif struct_style == "igloo" then
if struct_style == "igloo" then
return mcl_structures.generate_igloo(pos, rotation, pr)
elseif struct_style == "witch_hut" then
return mcl_structures.generate_witch_hut(pos, rotation)
@ -349,8 +347,6 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr, callback)
return mcl_structures.generate_ice_spike_large(pos, rotation)
elseif struct_style == "boulder" then
return mcl_structures.generate_boulder(pos, rotation, pr)
elseif struct_style == "fossil" then
return mcl_structures.generate_fossil(pos, rotation, pr)
elseif struct_style == "end_exit_portal" then
return mcl_structures.generate_end_exit_portal(pos, rotation, pr, callback)
elseif struct_style == "end_exit_portal_open" then
@ -380,17 +376,6 @@ function mcl_structures.generate_end_portal(pos, rotation, pr)
end
end
function mcl_structures.generate_desert_well(pos, rot)
local newpos = {x=pos.x,y=pos.y-2,z=pos.z}
local path = modpath.."/schematics/mcl_structures_desert_well.mts"
return mcl_structures.place_schematic({
pos = newpos,
schematic = path,
rotation = rot or "0",
force_placement = true
})
end
function mcl_structures.generate_igloo(pos, rotation, pr)
-- Place igloo
local success, rotation = mcl_structures.generate_igloo_top(pos, pr)
@ -590,24 +575,6 @@ function mcl_structures.generate_ice_spike_large(pos, rotation)
return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
end
function mcl_structures.generate_fossil(pos, rotation, pr)
-- Generates one out of 8 possible fossil pieces
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
local fossils = {
"mcl_structures_fossil_skull_1.mts", -- 4×5×5
"mcl_structures_fossil_skull_2.mts", -- 5×5×5
"mcl_structures_fossil_skull_3.mts", -- 5×5×7
"mcl_structures_fossil_skull_4.mts", -- 7×5×5
"mcl_structures_fossil_spine_1.mts", -- 3×3×13
"mcl_structures_fossil_spine_2.mts", -- 5×4×13
"mcl_structures_fossil_spine_3.mts", -- 7×4×13
"mcl_structures_fossil_spine_4.mts", -- 8×5×13
}
local r = pr:next(1, #fossils)
local path = modpath.."/schematics/"..fossils[r]
return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true)
end
function mcl_structures.generate_end_exit_portal(pos, rot, pr, callback)
local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts"
return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true, nil, callback)
@ -623,4 +590,15 @@ function mcl_structures.generate_end_gateway_portal(pos, rot)
return mcl_structures.place_schematic(pos, path, rot or "0", nil, true)
end
local chunk_square = mcl_mapgen.CS_NODES * mcl_mapgen.CS_NODES
local block_square = mcl_mapgen.BS * mcl_mapgen.BS
function mcl_structures.from_16x16_to_chunk_inverted_chance(x)
return math.floor(x * chunk_square / 256 + 0.5)
end
function mcl_structures.from_16x16_to_block_inverted_chance(x)
return math.floor(x * block_square / 256 + 0.5)
end
dofile(modpath .. "/structures.lua")

View File

@ -5,6 +5,8 @@ local chance_per_chunk = 9
local noise_multiplier = 1.3
local random_offset = 132
local struct_threshold = chance_per_chunk - 1
local scanning_ratio = 0.0003
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
local node_list = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:stone", "mcl_core:granite", "mcl_core:gravel", "mcl_core:diorite"}
@ -62,10 +64,18 @@ local function on_placed(p1, rotation, pr, size)
end
end
-- Find chests.
local chests = minetest.find_nodes_in_area(p1, {x = p2.x, y = p1.y + 5, z = p2.z}, "mcl_chests:trapped_chest_small")
-- Initialize some nodes
local chest_node = "mcl_chests:trapped_chest_small"
local lever_node = "mesecons_walllever:wall_lever_off"
local nodes = minetest.find_nodes_in_area(p1, {x = p2.x, y = p1.y + 5, z = p2.z}, {chest_node, lever_node}, true)
-- Add desert temple loot into chests
local levers = nodes[lever_node]
for _, pos in pairs(levers) do
mcl_structures.init_node_construct(pos)
end
-- Add loot into chests TODO: fix items
local chests = nodes[chest_node]
for c=1, #chests do
local lootitems = mcl_loot.get_multi_loot({
{
@ -107,7 +117,6 @@ local function on_placed(p1, rotation, pr, size)
local inv = meta:get_inventory()
mcl_loot.fill_inventory(inv, "main", lootitems, pr)
end
end
local function place(pos, rotation, pr)
@ -152,7 +161,7 @@ mcl_structures.register_structure({
deco_type = "simple",
place_on = node_list,
flags = "all_floors",
fill_ratio = 0.0003,
fill_ratio = scanning_ratio,
y_min = -13,
y_max = mcl_mapgen.overworld.max,
height = 1,

View File

@ -1,4 +1,4 @@
name = mcl_structures
author = Wuzzy, kay27, cora
description = Structures for MineClone 2/5
depends = mcl_loot, mcl_mapgen
depends = mcl_loot, mcl_mapgen, mcl_worlds

View File

@ -5,6 +5,7 @@ local chance_per_chunk = 15
local noise_multiplier = 1
local random_offset = 133
local struct_threshold = chance_per_chunk - 1
local scanning_ratio = 0.00021
local mcl_structures_get_perlin_noise_level = mcl_structures.get_perlin_noise_level
local node_list = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:stone", "mcl_core:granite", "mcl_core:gravel", "mcl_core:diorite"}
@ -68,10 +69,18 @@ local function on_placed(p1, rotation, pr, size)
end
end
-- Find chests.
local chests = minetest.find_nodes_in_area(p1, {x = p2.x, y = p1.y + 5, z = p2.z}, "mcl_chests:trapped_chest_small")
-- Initialize some nodes
local chest_node = "mcl_chests:trapped_chest_small"
local lever_node = "mesecons_walllever:wall_lever_off"
local nodes = minetest.find_nodes_in_area(p1, {x = p2.x, y = p1.y + 5, z = p2.z}, {chest_node, lever_node}, true)
-- Add desert temple loot into chests
local levers = nodes[lever_node]
for _, pos in pairs(levers) do
mcl_structures.init_node_construct(pos)
end
-- Add loot into chests TODO: fix items
local chests = nodes[chest_node]
for c=1, #chests do
local lootitems = mcl_loot.get_multi_loot({
{
@ -158,7 +167,7 @@ mcl_structures.register_structure({
deco_type = "simple",
place_on = node_list,
flags = "all_floors",
fill_ratio = 0.00021,
fill_ratio = scanning_ratio,
y_min = -20,
y_max = mcl_mapgen.overworld.max,
height = 1,

View File

@ -3,9 +3,10 @@ local modpath = minetest.get_modpath(modname)
if not mcl_mapgen.singlenode then
dofile(modpath .. "/desert_temple.lua")
dofile(modpath .. "/desert_well.lua")
dofile(modpath .. "/fossil.lua")
dofile(modpath .. "/jungle_temple.lua")
dofile(modpath .. "/nice_jungle_temple.lua")
dofile(modpath .. "/stronghold.lua")
dofile(modpath .. "/noise_indicator.lua")
dofile(modpath .. "/stronghold.lua")
end