witch hut, boulders, ice-spikes -> new api

This commit is contained in:
cora 2022-06-24 17:54:34 +02:00
parent dfbb832f96
commit 14cd360214
3 changed files with 86 additions and 89 deletions

View file

@ -3397,6 +3397,7 @@ local function register_decorations()
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder.mts", schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder.mts",
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
rotation = "random",
}) })
-- Small mossy cobblestone boulder (2×2) -- Small mossy cobblestone boulder (2×2)
@ -3417,6 +3418,7 @@ local function register_decorations()
y_max = mcl_vars.mg_overworld_max, y_max = mcl_vars.mg_overworld_max,
schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder_small.mts", schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder_small.mts",
flags = "place_center_x, place_center_z", flags = "place_center_x, place_center_z",
rotation = "random",
}) })
-- Cacti -- Cacti

View file

@ -1331,7 +1331,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
end end
end end
-- Witch hut -- Witch hut (v6)
if ground_y <= 0 and nn == "mcl_core:dirt" then if ground_y <= 0 and nn == "mcl_core:dirt" then
local prob = minecraft_chunk_probability(48, minp, maxp) local prob = minecraft_chunk_probability(48, minp, maxp)
if pr:next(1, prob) == 1 then if pr:next(1, prob) == 1 then
@ -1340,22 +1340,13 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local swampland_shore = minetest.get_biome_id("Swampland_shore") local swampland_shore = minetest.get_biome_id("Swampland_shore")
-- Where do witches live? -- Where do witches live?
local here_be_witches = false
if mg_name == "v6" then
-- v6: In Normal biome -- v6: In Normal biome
if biomeinfo.get_v6_biome(p) == "Normal" then if biomeinfo.get_v6_biome(p) == "Normal" then
here_be_witches = true here_be_witches = true
end end
else local here_be_witches = false
-- Other mapgens: In swampland biome if mg_name == "v6" and here_be_witches then
local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp)
if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then
here_be_witches = true
end
end
if here_be_witches then
local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270"
local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1}
local size local size
@ -1375,9 +1366,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
-- FIXME: For some mysterious reason (black magic?) this -- FIXME: For some mysterious reason (black magic?) this
-- function does sometimes NOT spawn the witch hut. One can only see the -- function does sometimes NOT spawn the witch hut. One can only see the
-- oak wood nodes in the water, but no hut. :-/ -- oak wood nodes in the water, but no hut. :-/
mcl_structures.call_struct(place, "witch_hut", r, pr) mcl_structures.place_structure(place,mcl_structures.registered_structures["witch_hut"],pr)
-- TODO: Spawn witch in or around hut when the mob sucks less.
local function place_tree_if_free(pos, prev_result) local function place_tree_if_free(pos, prev_result)
local nn = minetest.get_node(pos).name local nn = minetest.get_node(pos).name
@ -1436,7 +1425,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
-- Ice spikes in v6 -- Ice spikes in v6
-- In other mapgens, ice spikes are generated as decorations. -- In other mapgens, ice spikes are generated as decorations.
if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then if mg_name == "v6" and nn == "mcl_core:snowblock" then
local spike = pr:next(1,58000) local spike = pr:next(1,58000)
if spike < 3 then if spike < 3 then
-- Check surface -- Check surface
@ -1446,7 +1435,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
if #surface >= 9 and #spruce_collisions == 0 then if #surface >= 9 and #spruce_collisions == 0 then
mcl_structures.call_struct(p, "ice_spike_large", nil, pr) mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_large"],pr)
end end
elseif spike < 100 then elseif spike < 100 then
-- Check surface -- Check surface
@ -1457,7 +1446,7 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"})
if #surface >= 25 and #spruce_collisions == 0 then if #surface >= 25 and #spruce_collisions == 0 then
mcl_structures.call_struct(p, "ice_spike_small", nil, pr) mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_small"],pr)
end end
end end
end end
@ -2188,6 +2177,7 @@ mcl_mapgen_core.register_generator("structures",nil, function(minp, maxp, blocks
local has_struct = {} local has_struct = {}
local poshash = minetest.hash_node_position(minp) local poshash = minetest.hash_node_position(minp)
for _,struct in pairs(mcl_structures.registered_structures) do for _,struct in pairs(mcl_structures.registered_structures) do
if struct.deco_id then
local has = false local has = false
if has_struct[struct.name] == nil then has_struct[struct.name] = {} end if has_struct[struct.name] == nil then has_struct[struct.name] = {} end
for _, pos in pairs(gennotify["decoration#"..struct.deco_id] or {}) do for _, pos in pairs(gennotify["decoration#"..struct.deco_id] or {}) do
@ -2199,4 +2189,5 @@ mcl_mapgen_core.register_generator("structures",nil, function(minp, maxp, blocks
end end
end end
end end
end
end, 100, true) end, 100, true)

View file

@ -77,14 +77,6 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr)
end end
if struct_style == "igloo" then if struct_style == "igloo" then
return mcl_structures.generate_igloo(pos, rotation, pr) return mcl_structures.generate_igloo(pos, rotation, pr)
elseif struct_style == "witch_hut" then
return mcl_structures.generate_witch_hut(pos, rotation)
elseif struct_style == "ice_spike_small" then
return mcl_structures.generate_ice_spike_small(pos, rotation)
elseif struct_style == "ice_spike_large" then
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 elseif struct_style == "fossil" then
return mcl_structures.generate_fossil(pos, rotation, pr) return mcl_structures.generate_fossil(pos, rotation, pr)
elseif struct_style == "end_exit_portal" then elseif struct_style == "end_exit_portal" then
@ -256,21 +248,6 @@ function mcl_structures.generate_igloo_basement(pos, orientation, pr)
mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, igloo_placement_callback, pr) mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, igloo_placement_callback, pr)
end end
function mcl_structures.generate_boulder(pos, rotation, pr)
-- Choose between 2 boulder sizes (2×2×2 or 3×3×3)
local r = pr:next(1, 10)
local path
if r <= 3 then
path = modpath.."/schematics/mcl_structures_boulder_small.mts"
else
path = modpath.."/schematics/mcl_structures_boulder.mts"
end
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
return minetest.place_schematic(newpos, path, rotation) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995
end
local function spawn_witch(p1,p2) local function spawn_witch(p1,p2)
local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"}) local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"})
if c then if c then
@ -287,33 +264,6 @@ local function spawn_witch(p1,p2)
end end
end end
local function hut_placement_callback(p1, p2, size, orientation, pr)
if not p1 or not p2 then return end
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
for i = 1, #legs do
while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
legs[i].y = legs[i].y - 1
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
end
end
spawn_witch(p1,p2)
end
function mcl_structures.generate_witch_hut(pos, rotation, pr)
local path = modpath.."/schematics/mcl_structures_witch_hut.mts"
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr)
end
function mcl_structures.generate_ice_spike_small(pos, rotation)
local path = modpath.."/schematics/mcl_structures_ice_spike_small.mts"
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_ice_spike_large(pos, rotation)
local path = modpath.."/schematics/mcl_structures_ice_spike_large.mts"
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) function mcl_structures.generate_fossil(pos, rotation, pr)
-- Generates one out of 8 possible fossil pieces -- Generates one out of 8 possible fossil pieces
local newpos = {x=pos.x,y=pos.y-1,z=pos.z} local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
@ -480,6 +430,45 @@ dofile(modpath.."/desert_temple.lua")
dofile(modpath.."/jungle_temple.lua") dofile(modpath.."/jungle_temple.lua")
dofile(modpath.."/ocean_ruins.lua") dofile(modpath.."/ocean_ruins.lua")
local function hut_placement_callback(pos,def,pr)
local hl = def.sidelen / 2
local p1 = vector.offset(pos,-hl,-hl,-hl)
local p2 = vector.offset(pos,hl,hl,hl)
if not p1 or not p2 then return end
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
local tree = {}
for i = 1, #legs do
while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
legs[i].y = legs[i].y - 1
table.insert(tree,legs[i])
end
end
minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2})
spawn_witch(p1,p2)
end
mcl_structures.register_structure("witch_hut",{
place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"},
noise_params = {
offset = 0,
scale = 0.0012,
spread = {x = 250, y = 250, z = 250},
seed = 233,
octaves = 3,
persist = 0.001,
flags = "absvalue",
},
flags = "place_center_x, place_center_z, liquid_surface, force_placement",
sidelen = 5,
chunk_probability = 64,
y_max = mcl_vars.mg_overworld_max,
y_min = 1,
--y_offset = function(pr) return pr:next(-4,1) end,
y_offset = 0,
biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" },
filenames = { modpath.."/schematics/mcl_structures_witch_hut.mts" },
after_place = hut_placement_callback,
})
mcl_structures.register_structure("desert_well",{ mcl_structures.register_structure("desert_well",{
place_on = {"group:sand"}, place_on = {"group:sand"},
noise_params = { noise_params = {
@ -503,9 +492,32 @@ mcl_structures.register_structure("desert_well",{
filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" }, filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" },
}) })
mcl_structures.register_structure("boulder",{
flags = "place_center_x, place_center_z",
sidelen = 4,
filenames = {
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder_small.mts",
modpath.."/schematics/mcl_structures_boulder.mts",
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_small",{
sidelen = 3,
filenames = {
modpath.."/schematics/mcl_structures_ice_spike_small.mts"
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
mcl_structures.register_structure("ice_spike_large",{
sidelen = 6,
filenames = {
modpath.."/schematics/mcl_structures_ice_spike_large.mts"
},
},true) --is spawned as a normal decoration. this is just for /spawnstruct
-- Debug command -- Debug command
minetest.register_chatcommand("spawnstruct", { minetest.register_chatcommand("spawnstruct", {
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon", params = "igloo | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon",
description = S("Generate a pre-defined structure near your position."), description = S("Generate a pre-defined structure near your position."),
privs = {debug = true}, privs = {debug = true},
func = function(name, param) func = function(name, param)
@ -521,16 +533,8 @@ minetest.register_chatcommand("spawnstruct", {
local message = S("Structure placed.") local message = S("Structure placed.")
if param == "igloo" then if param == "igloo" then
mcl_structures.generate_igloo(pos, rot, pr) mcl_structures.generate_igloo(pos, rot, pr)
elseif param == "witch_hut" then
mcl_structures.generate_witch_hut(pos, rot, pr)
elseif param == "boulder" then
mcl_structures.generate_boulder(pos, rot, pr)
elseif param == "fossil" then elseif param == "fossil" then
mcl_structures.generate_fossil(pos, rot, pr) mcl_structures.generate_fossil(pos, rot, pr)
elseif param == "ice_spike_small" then
mcl_structures.generate_ice_spike_small(pos, rot, pr)
elseif param == "ice_spike_large" then
mcl_structures.generate_ice_spike_large(pos, rot, pr)
elseif param == "end_exit_portal" then elseif param == "end_exit_portal" then
mcl_structures.generate_end_exit_portal(pos, rot, pr) mcl_structures.generate_end_exit_portal(pos, rot, pr)
elseif param == "end_exit_portal_open" then elseif param == "end_exit_portal_open" then