diff --git a/decogen.lua b/decogen.lua index a56c748..022e6b6 100644 --- a/decogen.lua +++ b/decogen.lua @@ -25,12 +25,8 @@ local plant_noise = {offset = 0.0, scale = 1.0, spread = {x = 200, y = 200, z = -- Air needs to be placed prior to decorations. -fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, biome_ids, underzone, dis_map) +fun_caves.decogen = function(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone, dis_map) csize = vector.add(vector.subtract(maxp, minp), 1) - local biomemap - if fun_caves.use_bi_hi then - biomemap = minetest.get_mapgen_object("biomemap") - end local map_max = {x = csize.x, y = csize.y + 2, z = csize.z} local map_min = {x = minp.x, y = minp.y - 1, z = minp.z} diff --git a/mapgen.lua b/mapgen.lua index f1e47a9..106a9f6 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -364,7 +364,7 @@ local function generate(p_minp, p_maxp, seed) math.randomseed(minetest.get_perlin(seed_noise):get2d({x=minp.x, y=minp.z})) local write = false - local write_p2 = false + local write_p2, write_p4 = false, false local underzone for _, uz in pairs(fun_caves.underzones) do local avg = (minp.y + maxp.y) / 2 @@ -374,6 +374,7 @@ local function generate(p_minp, p_maxp, seed) end local aster = false + local true_casket if minp.y > 17200 then -- nop elseif minp.y > 11000 then @@ -388,21 +389,29 @@ local function generate(p_minp, p_maxp, seed) fun_caves.fortress(minp, maxp, data, area, node) write = true else - local write1, write2, write3, h2 + local write1, write2, write3, write4, h2 write1, h2 = fun_caves.cavegen(minp, maxp, data, area, node, heightmap, underzone) if h2 then heightmap = h2 end - write2, write_p2 = fun_caves.decogen(minp, maxp, data, p2data, area, node, heightmap, biome_ids, underzone) + local biomemap + if fun_caves.use_bi_hi then + biomemap = minetest.get_mapgen_object("biomemap") + end + + write2, write_p2 = fun_caves.decogen(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone) write3 = fun_caves.treegen(minp, maxp, data, p2data, area, node) - write = write1 or write2 or write3 + if not write3 then + write4, write_p4, true_casket = fun_caves.pyramid(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap) + end + write = write1 or write2 or write3 or write4 end if write then vm:set_data(data) - if write_p2 then + if write_p2 or write_p4 then vm:set_param2_data(p2data) end @@ -418,6 +427,13 @@ local function generate(p_minp, p_maxp, seed) end vm:update_liquids() vm:write_to_map() + + if true_casket then + vm:update_map() + local meta = minetest.get_meta(true_casket) + local id = meta:set_string('true', 'true') + --print('* True casket at '..minetest.pos_to_string(true_casket)) + end end -- Deal with memory issues. This, of course, is supposed to be automatic. @@ -435,6 +451,7 @@ dofile(fun_caves.path .. "/cavegen.lua") dofile(fun_caves.path .. "/cloudgen.lua") dofile(fun_caves.path .. "/decogen.lua") dofile(fun_caves.path .. "/fortress.lua") +dofile(fun_caves.path .. "/pyramid.lua") dofile(fun_caves.path .. "/treegen.lua") dofile(fun_caves.path .. "/skyseagen.lua") diff --git a/mobs.lua b/mobs.lua index 8c03ce5..21d3092 100644 --- a/mobs.lua +++ b/mobs.lua @@ -635,6 +635,7 @@ if minetest.registered_entities["mobs_monster:sand_monster"] then mobs.spawning_mobs["fun_caves:sand_monster"] = true mobs:register_spawn("fun_caves:sand_monster", {"default:sand"}, 20, 0, 4000, 3, -50) + mobs:register_spawn("fun_caves:sand_monster", {"fun_caves:pyramid_1"}, default.LIGHT_MAX - 1, 0, 200, 5, 31000) mobs:register_egg("fun_caves:sand_monster", "Deep Sand Monster", "default_sand.png", 1) end diff --git a/pyramid.lua b/pyramid.lua new file mode 100644 index 0000000..26b1e2b --- /dev/null +++ b/pyramid.lua @@ -0,0 +1,143 @@ +local max_depth = 31000 + +-- pyramid stone +newnode = fun_caves.clone_node("default:sandstone") +newnode.description = "Pyramid Stone" +newnode.groups.pyramid = 1 +newnode.drop = 'default:sandstone' +minetest.register_node("fun_caves:pyramid_1", newnode) + +local newnode = fun_caves.clone_node("default:chest") +newnode.description = "Treasure Casket" +local chest_formspec = + "size[8,9]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + +local filler = {'default:apple 10', 'default:coal_lump 10', 'default:wood 10'} + +local gems = {'fun_caves:moonstone', 'fun_caves:coral_gem', 'fun_caves:garnet', 'fun_caves:aquamarine', 'fun_caves:zoisite'} + +newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + local true_casket = meta:get_string('true') + if true_casket ~= 'true' then + clicker:set_hp(clicker:get_hp() - 2) + --print('* ouch!') + return + end + + local ready = meta:get_string('formspec') + if ready == '' then + meta:set_string("formspec", chest_formspec) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + for i = 1, math.random(4) do + inv:add_item('main', filler[math.random(#filler)]) + end + inv:add_item('main', gems[math.random(#gems)]) + end +end +minetest.register_node("fun_caves:casket", newnode) + + +local pyramid_biomes = {} +for _, i in pairs({"rainforest", "desert", "desertstone_grassland", }) do + pyramid_biomes[i] = true +end + +local pyramid_noise_1 = {offset = 0, scale = 1, seed = -6012, spread = {x = 20, y = 10, z = 20}, octaves = 6, persist = 1, lacunarity = 2} + + +fun_caves.pyramid = function(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap) + if math.random(10) ~= 1 then + return + end + + if biomemap then + local biome = biome_ids[biomemap[3240]] + if not pyramid_biomes[biome] then + return + end + --print('* Creating pyramid in '..biome) + elseif math.random(5) ~= 1 then + return + end + + + local min_y = 80 + local index = 0 + for z = minp.z, maxp.z do + local dz = z - minp.z + for x = minp.x, maxp.x do + local dx = x - minp.x + index = index + 1 + if dz > 8 and dz < 72 and dx > 8 and dx < 72 and heightmap[index] - minp.y < 0 then + return + elseif heightmap[index] - minp.y < min_y then + min_y = heightmap[index] - minp.y + end + end + end + if min_y >= 72 or heightmap[3240] >= 72 then + return + end + + local base_height = math.min(min_y, 35) + + local csize = vector.add(vector.subtract(maxp, minp), 1) + local map_max = {x = csize.x, y = csize.y, z = csize.z} + local map_min = {x = minp.x, y = minp.y, z = minp.z} + + local pyramid_1 = minetest.get_perlin_map(pyramid_noise_1, map_max):get3dMap_flat(map_min) + + local write = true + local p2write = false + local caskets = {} + + index = 0 + local index3d = 0 + for z = minp.z, maxp.z do + local dz = z - minp.z + for x = minp.x, maxp.x do + local dx = x - minp.x + index = index + 1 + index3d = math.floor((z - minp.z) / 5) * (csize.y) * csize.x + math.floor((x - minp.x) / 5) + 1 + local ivm = area:index(x, minp.y, z) + + --pyramid_1[index] = math.floor(pyramid_1[index] + 0.5) + for y = minp.y, maxp.y do + local dy = y - minp.y + + if dy >= base_height + 3 and dy <= base_height + 37 - math.max(math.abs(dx - 40), math.abs(dz - 40)) and pyramid_1[index3d] > 0 then + if data[ivm - area.ystride] == node['fun_caves:pyramid_1'] and math.random(100) == 1 then + data[ivm] = node['fun_caves:casket'] + caskets[#caskets+1] = {x=x, y=y, z=z} + else + data[ivm] = node['air'] + end + elseif dy >= base_height and dy <= base_height + 40 - math.max(math.abs(dx - 40), math.abs(dz - 40)) then + data[ivm] = node['fun_caves:pyramid_1'] + end + + ivm = ivm + area.ystride + if dy % 5 == 0 then + index3d = index3d + csize.x + end + end + end + end + + if #caskets > 0 then + return write, p2write, caskets[math.random(#caskets)] + else + return write, p2write + end +end