diff --git a/nether/common.lua b/nether/common.lua index 0ec5eb3..b75cec3 100644 --- a/nether/common.lua +++ b/nether/common.lua @@ -1,6 +1,8 @@ dofile(nether.path .. "/settings.lua") +local in_mapgen_env = nether.env_type == "ssm_mapgen" + -- vars nether.v = {} local v = nether.v @@ -132,14 +134,16 @@ function nether.query_contents() end if nether.log_level >= 1 then + local mod_prefix = in_mapgen_env and "[nether(mg)] " or "[nether] " + function nether:inform(msg, spam, t) if spam <= self.log_level then local info if t then - info = "[nether] " .. msg .. (" after ca. %.3g s"):format( + info = mod_prefix .. msg .. (" after ca. %.3g s"):format( (minetest.get_us_time() - t) / 1000000) else - info = "[nether] " .. msg + info = mod_prefix .. msg end print(info) if self.log_to_chat then diff --git a/nether/grow_structures.lua b/nether/grow_structures.lua index 0186173..8107adb 100644 --- a/nether/grow_structures.lua +++ b/nether/grow_structures.lua @@ -1,17 +1,24 @@ -local function r_area(manip, width, height, pos) +local netherstructure_height = 6 + +local function vmanip_with_r_area(width, height, pos) + local manip = minetest.get_voxel_manip() local emerged_pos1, emerged_pos2 = manip:read_from_map( {x=pos.x-width, y=pos.y, z=pos.z-width}, {x=pos.x+width, y=pos.y+height, z=pos.z+width} ) - return VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) + return manip, VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) +end + +local function inform_grow(pos, t1, name, generated) + nether:inform(name.." grew at " .. minetest.pos_to_string(pos), + generated and 3 or 2, t1) end local function set_vm_data(manip, nodes, pos, t1, name, generated) manip:set_data(nodes) manip:write_to_map(not generated) - nether:inform(name.." grew at " .. minetest.pos_to_string(pos), - generated and 3 or 2, t1) + inform_grow(pos, t1, name, generated) end local c, contents_defined @@ -22,20 +29,10 @@ local function define_contents() end end -function nether.grow_netherstructure(pos, generated) - local t1 = minetest.get_us_time() - +local function grow_netherstructure_into_raw(area, nodes, pos, generated) define_contents() - if not pos.x then print(dump(pos)) - nether:inform("Error: "..dump(pos), 1) - return - end - - local height = 6 - local manip = minetest.get_voxel_manip() - local area = r_area(manip, 2, height, pos) - local nodes = manip:get_data() + local height = netherstructure_height local vi = area:indexp(pos) for _ = 0, height-1 do @@ -75,9 +72,37 @@ function nether.grow_netherstructure(pos, generated) end end end - set_vm_data(manip, nodes, pos, t1, "blood", generated) end +function nether.grow_netherstructure_into(area, nodes, pos, generated) + local t1 = minetest.get_us_time() + + if not pos.x then print(dump(pos)) + nether:inform("Error: "..dump(pos), 1) + return + end + + grow_netherstructure_into_raw(area, nodes, pos, generated) + + inform_grow(pos, t1, "blood", generated) +end + +function nether.grow_netherstructure(pos, generated) + local t1 = minetest.get_us_time() + + if not pos.x then print(dump(pos)) + nether:inform("Error: "..dump(pos), 1) + return + end + + local height = netherstructure_height + local manip, area = vmanip_with_r_area(2, height, pos) + local nodes = manip:get_data() + + grow_netherstructure_into_raw(area, nodes, pos, generated) + + set_vm_data(manip, nodes, pos, t1, "blood", generated) +end local poshash = minetest.hash_node_position local pos_from_hash = minetest.get_position_from_hash diff --git a/nether/init.lua b/nether/init.lua index 63845ee..c428204 100644 --- a/nether/init.lua +++ b/nether/init.lua @@ -17,7 +17,10 @@ if not rawget(_G, "nether") then nether = {} end -nether.path = minetest.get_modpath"nether" +-- similar to INIT +nether.env_type = "ssm" -- server-side-modding + +nether.path = minetest.get_modpath("nether") local path = nether.path dofile(path .. "/common.lua") @@ -28,9 +31,43 @@ dofile(path .. "/pearl.lua") dofile(path .. "/grow_structures.lua") -dofile(path .. "/mapgen.lua") +if minetest.register_mapgen_script then + minetest.log("info", "nether mapgen running in mapgen env") + minetest.register_mapgen_script(path .. "/init_emerge.lua") + minetest.set_gen_notify("custom", nil, + {"nether:please_grow_trees", "nether:please_fix_light"}) + + minetest.register_on_generated(function(minp, maxp, blockseed) + local t0 = minetest.get_us_time() + + local gennotify = minetest.get_mapgen_object("gennotify") + + -- forest trees + local trees_hashed = gennotify.custom["nether:please_grow_trees"] or {} + for i = 1, #trees_hashed do + local pos = minetest.get_position_from_hash(trees_hashed[i]) + nether.grow_tree(pos, true) + end + + if #trees_hashed > 0 then + nether:inform(#trees_hashed .. " trees set", 2, t0) + end + + -- fix light + local fixlight_area = gennotify.custom["nether:please_fix_light"] + if fixlight_area then + t0 = minetest.get_us_time() + minetest.fix_light(fixlight_area[1], fixlight_area[2]) + nether:inform("light fixed", 2, t0) + end + end) + +else + minetest.log("info", "nether mapgen running in main env") + dofile(path .. "/mapgen.lua") +end --abms diff --git a/nether/init_emerge.lua b/nether/init_emerge.lua new file mode 100644 index 0000000..69d5833 --- /dev/null +++ b/nether/init_emerge.lua @@ -0,0 +1,13 @@ + +-- This is run in mapgen env (see register_mapgen_script) + +nether = {} +nether.env_type = "ssm_mapgen" + +nether.path = minetest.get_modpath("nether") +local path = nether.path + +dofile(path .. "/common.lua") +dofile(path .. "/grow_structures.lua") + +dofile(path .. "/mapgen.lua") diff --git a/nether/mapgen.lua b/nether/mapgen.lua index 96dbcc2..84596a7 100644 --- a/nether/mapgen.lua +++ b/nether/mapgen.lua @@ -1,5 +1,6 @@ local path = nether.path +local in_mapgen_env = nether.env_type == "ssm_mapgen" -- vars local v = nether.v @@ -189,7 +190,7 @@ local data = {} local structures_enabled = true local vine_maxlength = math.floor(NETHER_HEIGHT/4+0.5) -- Create the Nether -minetest.register_on_generated(function(minp, maxp, seed) +local function on_generated(minp, maxp, seed) --avoid big map generation if not (maxp.y >= NETHER_BOTTOM-100 and minp.y <= nether_start) then return @@ -442,39 +443,77 @@ minetest.register_on_generated(function(minp, maxp, seed) end end end + + nether:inform("most stuff set", 2, t1) + + local t2 = minetest.get_us_time() + local bl_cnt = 0 + local tr_cnt = 0 + local tr_snd_cnt = 0 + + if structures_enabled then -- Blood netherstructures + bl_cnt = #tab + for i = 1, #tab do + nether.grow_netherstructure_into(area, data, tab[i], true) + end + end + + if bl_cnt > 0 then + nether:inform(bl_cnt .. " blood structures set", 2, t2) + end + + t2 = minetest.get_us_time() vm:set_data(data) -- vm:set_lighting(12) -- vm:calc_lighting() -- vm:update_liquids() - vm:write_to_map(false) - - nether:inform("nodes set", 2, t1) - - local t2 = minetest.get_us_time() - local tr_bl_cnt = 0 - - if structures_enabled then -- Blood netherstructures - tr_bl_cnt = #tab - for i = 1,tr_bl_cnt do - nether.grow_netherstructure(tab[i], true) - end - end - - if forest_possible then -- Forest trees - tr_bl_cnt = tr_bl_cnt + #trees - for i = 1,#trees do - nether.grow_tree(trees[i], true) - end - end - - if tr_bl_cnt > 0 then - nether:inform(tr_bl_cnt .. " trees and blood structures set", 2, t2) + if not in_mapgen_env then + vm:write_to_map(false) end + nether:inform("data written", 2, t2) t2 = minetest.get_us_time() - minetest.fix_light(minp, maxp) + if forest_possible then -- Forest trees + if in_mapgen_env then + -- Trees can get too big (>16 nodes in one direction) for usual + -- overgeneration onion layer. nether.grow_tree will make new vmanips + -- to emerge blank (= ignore-filled) blocks to overcome this. But the + -- main server thread needs to do this. + tr_snd_cnt = #trees + local trees_hashed = {} + for i = 1, #trees do + trees_hashed[i] = minetest.hash_node_position(trees[i]) + end + assert(minetest.save_gen_notify("nether:please_grow_trees", trees_hashed)) + else + tr_cnt = #trees + for i = 1, #trees do + nether.grow_tree(trees[i], true) + end + end + end - nether:inform("light fixed", 2, t2) + if tr_cnt + tr_snd_cnt > 0 then + nether:inform(string.format("%s trees set, %s trees sent", + tr_cnt, tr_snd_cnt), 2, t2) + end + + if in_mapgen_env then + assert(minetest.save_gen_notify("nether:please_fix_light", {minp, maxp})) + else + t2 = minetest.get_us_time() + minetest.fix_light(minp, maxp) + + nether:inform("light fixed", 2, t2) + end nether:inform("done", 1, t1) -end) +end + +if in_mapgen_env then + minetest.register_on_generated(function(_, minp, maxp, blockseed) + return on_generated(minp, maxp, blockseed) + end) +else + minetest.register_on_generated(on_generated) +end