diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index ea3d70aba..bc697e359 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -87,7 +87,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { end local origin = user:get_pos() origin.y = origin.y + 1.5 - local strongholds = mcl_structures.get_registered_structures("stronghold") + local strongholds = mcl_structures.get_structure_data("stronghold") local dim = mcl_worlds.pos_to_dimension(origin) local is_creative = minetest.is_creative_enabled(user:get_player_name()) diff --git a/mods/MAPGEN/mcl_geodes/init.lua b/mods/MAPGEN/mcl_geodes/init.lua new file mode 100644 index 000000000..84acd973b --- /dev/null +++ b/mods/MAPGEN/mcl_geodes/init.lua @@ -0,0 +1,88 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,1,0), + vector.new(0,-1,0) +} + +local function set_node_no_bedrock(pos,node) + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function makegeode(pos,pr) + local size = pr:next(4,7) + local p1 = vector.offset(pos,-size,-size,-size) + local p2 = vector.offset(pos,size,size,size) + local calcite = {} + local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone"}) + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + if not nn[1] then return end + + for i=1,math.random(#nn) do + set_node_no_bedrock(nn[i],{name="mcl_amethyst:amethyst_block"}) + end + + for k,v in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_amethyst:amethyst_block"})) do + local all_amethyst = true + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + if an.name ~= "mcl_amethyst:amethyst_block" then + if minetest.get_item_group(an.name,"material_stone") > 0 then + set_node_no_bedrock(pp,{name="mcl_amethyst:calcite"}) + table.insert(calcite,pp) + if pr:next(1,5) == 1 then + set_node_no_bedrock(v,{name="mcl_amethyst:budding_amethyst_block"}) + end + all_amethyst = false + elseif an.name ~= "mcl_amethyst:amethyst_block" and an.name ~= "air" then + all_amethyst = false + end + end + end + if all_amethyst then set_node_no_bedrock(v,{name="air"}) end + end + + for _,v in pairs(calcite) do + for _,vv in pairs(minetest.find_nodes_in_area(vector.offset(v,-1,-1,-1),vector.offset(v,1,1,1),{"group:material_stone"})) do + set_node_no_bedrock(vv,{name="mcl_blackstone:basalt_smooth"}) + end + end + + for k,v in pairs(minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_amethyst:amethyst_block","mcl_amethyst:budding_amethyst_block"})) do + local r = pr:next(1,50) + if r < 10 then + set_node_no_bedrock(vector.offset(v,0,1,0),{name="mcl_amethyst:amethyst_cluster",param2=1}) + end + end + return true +end + +mcl_structures.register_structure("geode",{ + place_on = {"mcl_core:stone"}, + noise_params = { + offset = 0, + scale = 0.00022, + spread = {x = 250, y = 250, z = 250}, + seed = 7894353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + biomes = ocean_biomes, + y_max = -24, + y_min = mcl_vars.mg_overworld_min, + filenames = schems, + y_offset = function(pr) return pr:next(-4,-2) end, + place_func = function(pos,def,pr) + local p = vector.new(pos.x + pr:next(-30,30),pos.y,pos.z + pr:next(-30,30)) + return makegeode(p,pr) + end +}) diff --git a/mods/MAPGEN/mcl_geodes/mod.conf b/mods/MAPGEN/mcl_geodes/mod.conf new file mode 100644 index 000000000..cccb57108 --- /dev/null +++ b/mods/MAPGEN/mcl_geodes/mod.conf @@ -0,0 +1,3 @@ +name = mcl_geodes +author = cora +depends = mcl_init, mcl_structures diff --git a/mods/MAPGEN/mcl_shipwrecks/init.lua b/mods/MAPGEN/mcl_shipwrecks/init.lua index c9bf2c942..a3861a2c9 100644 --- a/mods/MAPGEN/mcl_shipwrecks/init.lua +++ b/mods/MAPGEN/mcl_shipwrecks/init.lua @@ -8,11 +8,11 @@ local pr = PseudoRandom(seed) --schematics by chmodsayshello local schems = { - "shipwreck_full_damaged", - "shipwreck_full_normal", - "shipwreck_full_back_damaged", - "shipwreck_half_front", - "shipwreck_half_back", + modpath.."/schematics/".."shipwreck_full_damaged"..".mts", + modpath.."/schematics/".."shipwreck_full_normal"..".mts", + modpath.."/schematics/".."shipwreck_full_back_damaged"..".mts", + modpath.."/schematics/".."shipwreck_half_front"..".mts", + modpath.."/schematics/".."shipwreck_half_back"..".mts", } local function get_supply_loot() @@ -41,7 +41,7 @@ local function get_supply_loot() --{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, - + } } end @@ -75,61 +75,105 @@ local function fill_chests(p1,p2) end end -local function get_ocean_biomes() - local r = {} - for k,_ in pairs(minetest.registered_biomes) do - if k:find("_ocean") then table.insert(r,k) end - end - return r -end -local function get_beach_biomes() - local r = {} - for k,_ in pairs(minetest.registered_biomes) do - if k:find("_beach") or k:find("_shore") then table.insert(r,k) end - end - return r -end +local ocean_biomes = { + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean" +} -minetest.register_node("mcl_shipwrecks:structblock", {drawtype="airlike", walkable = false, pointable = false,groups = {structblock=1,not_in_creative_inventory=1}}) +local beach_biomes = { + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore" +} -minetest.register_decoration({ - decoration = "mcl_shipwrecks:structblock", - deco_type = "simple", +mcl_structures.register_structure("shipwreck",{ place_on = {"group:sand","mcl_core:gravel"}, spawn_by = {"group:water"}, num_spawn_by = 4, - sidelen = 80, - fill_ratio = 0.00002, - flags = "place_center_x, place_center_z, force_placement", - biomes = get_ocean_biomes(), - y_max=water_level-4, -}) - ---rare beached variant -minetest.register_decoration({ - decoration = "mcl_shipwrecks:structblock", - deco_type = "simple", - place_on = {"group:sand","mcl_core:gravel","group:dirt"}, - spawn_by = {"group:water","air"}, - num_spawn_by = 4, - sidelen = 80, - fill_ratio=0.000001, - flags = "place_center_x, place_center_z, force_placement", - biomes = get_beach_biomes(), - y_max = water_level + 4, - y_min = water_level - 1, -}) - -minetest.register_lbm({ - name = "mcl_shipwrecks:struct_lbm", - run_at_every_load = true, - nodenames = {"mcl_shipwrecks:structblock"}, - action = function(pos, node) - minetest.set_node(pos,{name="air"}) - local file = modpath.."/schematics/"..schems[pr:next(1,#schems)]..".mts" - local pp = vector.offset(pos,0,pr:next(-4,-2),0) - mcl_structures.place_schematic(pp, file, "random", nil, true, "place_center_x,place_center_z", function() - fill_chests(vector.offset(pos,-20,-5,-20),vector.offset(pos,20,15,20)) - end,pr) + noise_params = { + offset = 0, + scale = 0.000022, + spread = {x = 250, y = 250, z = 250}, + seed = 3, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "force_placement", + biomes = ocean_biomes, + y_max = water_level-4, + y_min = mcl_vars.mg_overworld_min, + filenames = schems, + y_offset = function(pr) return pr:next(-4,-2) end, + after_place = function(pos) + fill_chests(vector.offset(pos,-20,-5,-20),vector.offset(pos,20,15,20)) end }) diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 083172a3c..2a362cc40 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -61,7 +61,7 @@ local function init_strongholds() end end - mcl_structures.register_structures("stronghold", table.copy(strongholds)) + mcl_structures.register_structure_data("stronghold", table.copy(strongholds)) strongholds_inited = true end diff --git a/mods/MAPGEN/mcl_structures/API.md b/mods/MAPGEN/mcl_structures/API.md new file mode 100644 index 000000000..23d93c712 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/API.md @@ -0,0 +1,29 @@ +# mcl_structures +Structure placement API for MCL2. + +## mcl_structures.register_structure(name,structure definition,nospawn) +If nospawn is truthy the structure will not be placed by mapgen and the decoration parameters can be omitted. This is intended for secondary structures the placement of which gets triggered by the placement of other structures. It can also be used to register testing structures so they can be used with /spawnstruct. + +### structure definition +{ + fill_ratio = OR noise = {}, + biomes = {}, + y_min =, + y_max =, + place_on = {}, + spawn_by = {}, + num_spawn_by = + flags = (default: "place_center_x, place_center_z, force_placement") + (same as decoration def) + y_offset =, --can be a number or a function returning a number + filenames = {} OR place_func = function(pos,def,pr) + -- filenames can be a list of any schematics accepted by mcl_structures.place_schematic / minetest.place_schematic + after_place = function(pos,def,pr) +} +## mcl_structures.registered_structures +Table of the registered structure defintions indexed by name. + +## mcl_structures.place_structure(pos, def, pr) +Places a structure using the mapgen placement function + +## mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua new file mode 100644 index 000000000..b3d0491ee --- /dev/null +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -0,0 +1,81 @@ +mcl_structures.registered_structures = {} + +function mcl_structures.place_structure(pos, def, pr) + if not def then return end + local y_offset = 0 + if type(def.y_offset) == "function" then + y_offset = def.y_offset(pr) + elseif def.y_offset then + y_offset = def.y_offset + end + if def.filenames then + local file = def.filenames[pr:next(1,#def.filenames)] + local pp = vector.offset(pos,0,y_offset,0) + mcl_structures.place_schematic(pp, file, "random", nil, true, "place_center_x,place_center_z",def.after_place,pr,{pos,def}) + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pos)) + return true + elseif def.place_func and def.place_func(pos,def,pr) then + if not def.after_place or ( def.after_place and def.after_place(pos,def,pr) ) then + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pos)) + return true + end + end + minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos)) +end + +function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly + local structblock = "mcl_structures:structblock_"..name + local flags = "place_center_x, place_center_z, force_placement" + local y_offset = 0 + local sbgroups = { structblock = 1, not_in_creative_inventory=1 } + if def.flags then flags = def.flags end + def.name = name + if nospawn then + sbgroups.structblock = nil + sbgroups.structblock_lbm = 1 + else + def.deco = minetest.register_decoration({ + name = "mcl_structures:deco_"..name, + decoration = structblock, + deco_type = "simple", + place_on = def.place_on, + spawn_by = def.spawn_by, + num_spawn_by = def.num_spawn_by, + sidelen = 80, + fill_ratio = def.fill_ratio, + noise_params = def.noise_params, + flags = flags, + biomes = def.biomes, + y_max = def.y_max, + y_min = def.y_min + }) + local deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name) + minetest.set_gen_notify({decoration=true}, { deco_id }) + minetest.register_on_generated(function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local pr = PseudoRandom(blockseed + 42) + for _, pos in pairs(gennotify["decoration#"..deco_id] or {}) do + local realpos = vector.offset(pos,0,-1,0) + minetest.remove_node(realpos) + mcl_structures.place_structure(realpos,def,pr) + end + end) + end + minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups}) + def.structblock = structblock + mcl_structures.registered_structures[name] = def +end + +--lbm for secondary structures (structblock included in base structure) +minetest.register_lbm({ + name = "mcl_structures:struct_lbm", + run_at_every_load = true, + nodenames = {"group:structblock_lbm"}, + action = function(pos, node) + local name = node.name:gsub("mcl_structures:structblock_","") + local def = mcl_structures.registered_structures[name] + if not def then return end + minetest.remove_node(pos) + mcl_structures.place_structure(pos) + end +}) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 5d3ecac6c..ffc25d40c 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -530,7 +530,7 @@ function mcl_structures.generate_desert_temple(pos, rotation, pr) mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true, nil, temple_placement_callback, pr) end -local registered_structures = {} +local structure_data = {} --[[ Returns a table of structure of the specified type. Currently the only valid parameter is "stronghold". @@ -543,18 +543,18 @@ Format of return value: TODO: Implement this function for all other structure types as well. ]] -function mcl_structures.get_registered_structures(structure_type) - if registered_structures[structure_type] then - return table.copy(registered_structures[structure_type]) +function mcl_structures.get_structure_data(structure_type) + if structure_data[structure_type] then + return table.copy(structure_data[structure_type]) else return {} end end -- Register a structures table for the given type. The table format is the same as for --- mcl_structures.get_registered_structures. -function mcl_structures.register_structures(structure_type, structures) - registered_structures[structure_type] = structures +-- mcl_structures.get_structure_data. +function mcl_structures.register_structure_data(structure_type, structures) + structure_data[structure_type] = structures end local function dir_to_rotation(dir) @@ -571,6 +571,8 @@ local function dir_to_rotation(dir) return "0" end +dofile(modpath.."/api.lua") + -- Debug command 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", @@ -619,6 +621,12 @@ minetest.register_chatcommand("spawnstruct", { message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true else + for n,d in pairs(mcl_structures.registered_structures) do + if n == param then + mcl_structures.place_structure(pos,d,pr) + return true,message + end + end message = S("Error: Unknown structure type. Please use “/spawnstruct ”.") errord = true end @@ -628,3 +636,10 @@ minetest.register_chatcommand("spawnstruct", { end end }) +minetest.register_on_mods_loaded(function() + local p = "" + for n,_ in pairs(mcl_structures.registered_structures) do + p = p .. " | "..n + end + minetest.registered_chatcommands["spawnstruct"].params = minetest.registered_chatcommands["spawnstruct"].params .. p +end) diff --git a/mods/MAPGEN/mcl_structures/mod.conf b/mods/MAPGEN/mcl_structures/mod.conf index 3150c7cec..c19113ad4 100644 --- a/mods/MAPGEN/mcl_structures/mod.conf +++ b/mods/MAPGEN/mcl_structures/mod.conf @@ -1,4 +1,4 @@ name = mcl_structures -author = Wuzzy -description = Structures for MCL2 +author = Wuzzy, cora +description = Structure placement for MCL2 depends = mcl_loot diff --git a/mods/MAPGEN/mcl_surface_pools/init.lua b/mods/MAPGEN/mcl_surface_pools/init.lua new file mode 100644 index 000000000..ed42f52bb --- /dev/null +++ b/mods/MAPGEN/mcl_surface_pools/init.lua @@ -0,0 +1,106 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(1,0,1), + vector.new(1,0,-1), + vector.new(-1,0,0), + vector.new(-1,0,1), + vector.new(-1,0,-1), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,-1,0) +} + +local function set_node_no_bedrock(pos,node) + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function airtower(pos) + for i=0,55 do + set_node_no_bedrock(vector.offset(pos,0,i,0),{name="air"}) + end +end + +local function makelake(pos,size,liquid,border,pr) + local node_under = minetest.get_node(vector.offset(pos,0,1,0)) + local p1 = vector.offset(pos,-size,-size,-size) + local p2 = vector.offset(pos,size,size,size) + local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone", "group:sand", "group:dirt"}) + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + if not nn[1] then return end + local y = pos.y + 1 + local lq = {} + for i=1,pr:next(1,#nn) do + if nn[i].y == y then + set_node_no_bedrock(nn[i],{name=liquid}) + airtower(vector.offset(nn[i],0,1,0)) + table.insert(lq,nn[i]) + end + end + + for k,v in pairs(lq) do + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + local un = minetest.get_node(vector.offset(pp,0,1,0)) + if not border then + if minetest.get_item_group(an.name,"solid") > 0 then + border = an.name + elseif minetest.get_item_group(minetest.get_node(nn[1]).name,"solid") > 0 then + border = minetest.get_node(nn[1]).name + else + border = "mcl_core:stone" + end + if border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end + end + if an.name ~= liquid then + set_node_no_bedrock(pp,{name=border}) + if un.name ~= liquid then + airtower(vector.offset(pp,0,1,0)) + end + end + end + end + return true +end + +mcl_structures.register_structure("lavapool",{ + place_on = {"group:sand", "group:dirt", "group:stone"}, + noise_params = { + offset = 0, + scale = 0.0000022, + spread = {x = 250, y = 250, z = 250}, + seed = 78375213, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:lava_source","mcl_core:stone",pr) + end +}) + +mcl_structures.register_structure("water_lake",{ + place_on = {"group:dirt","group:stone"}, + noise_params = { + offset = 0, + scale = 0.000032, + spread = {x = 250, y = 250, z = 250}, + seed = 734341353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:water_source",nil,pr) + end +}) diff --git a/mods/MAPGEN/mcl_surface_pools/mod.conf b/mods/MAPGEN/mcl_surface_pools/mod.conf new file mode 100644 index 000000000..bdc4319d4 --- /dev/null +++ b/mods/MAPGEN/mcl_surface_pools/mod.conf @@ -0,0 +1,3 @@ +name = mcl_surface_pools +author = cora +depends = mcl_init, mcl_structures