From 011affc46fe8ea3bad6a245ee72f10962183362f Mon Sep 17 00:00:00 2001 From: Duane Robertson Date: Sat, 21 May 2016 09:47:42 -0500 Subject: [PATCH] Major overhaul. Separate cave decorations from mapgen. --- deco.lua | 45 +++++++ deco_caves.lua | 317 ++++++++++++++++++++++++++++++++++++++++++++++++ deco_coral.lua | 97 +++++++++++++++ fungal_tree.lua | 8 +- init.lua | 1 + mapgen.lua | 295 ++++++-------------------------------------- 6 files changed, 497 insertions(+), 266 deletions(-) create mode 100644 deco.lua create mode 100644 deco_caves.lua create mode 100644 deco_coral.lua diff --git a/deco.lua b/deco.lua new file mode 100644 index 0000000..62a7a23 --- /dev/null +++ b/deco.lua @@ -0,0 +1,45 @@ + +-- I like having different stone scattered about. Sandstone forms +-- in layers. Desert stone... doesn't exist, but let's assume it's +-- another sedementary rock and place it similarly. +minetest.register_ore({ore_type="sheet", ore="default:sandstone", wherein="default:stone", clust_num_ores=250, clust_scarcity=60, clust_size=10, y_min=-1000, y_max=31000, noise_threshhold=0.1, noise_params={offset=0, scale=1, spread={x=256, y=256, z=256}, seed=4130293965, octaves=5, persist=0.60}, random_factor=1.0}) +minetest.register_ore({ore_type="sheet", ore="default:desert_stone", wherein="default:stone", clust_num_ores=250, clust_scarcity=60, clust_size=10, y_min=-1000, y_max=31000, noise_threshhold=0.1, noise_params={offset=0, scale=1, spread={x=256, y=256, z=256}, seed=163281090, octaves=5, persist=0.60}, random_factor=1.0}) + +minetest.register_node("fun_caves:sand_with_rocks", { + description = "Sand and rocks", + tiles = {"fun_caves_sand_with_rocks.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, + sounds = default.node_sound_sand_defaults(), + drop = {max_items=2, items={{items={"fun_caves:small_rocks"}, rarity=1}, {items={"default:sand"}, rarity=1}}}, +}) + +--minetest.register_decoration({ +-- deco_type = "simple", +-- place_on = {"default:dirt_with_grass"}, +-- sidelen = 80, +-- fill_ratio = 0.1, +-- biomes = {"rainforest", "desertstone_grassland"}, +-- y_min = 1, +-- y_max = 31000, +-- decoration = "default:junglegrass", +--}) + +minetest.register_craft({ + output = "default:stick 2", + recipe = { + {"default:cactus"} + } +}) + +minetest.add_group("default:cactus", {oddly_breakable_by_hand=1}) + +dofile(fun_caves.path.."/deco_caves.lua") +--dofile(fun_caves.path.."/deco_coral.lua") +--dofile(fun_caves.path.."/deco_dirt.lua") +--dofile(fun_caves.path.."/deco_trees.lua") +--dofile(fun_caves.path.."/deco_plants.lua") +--dofile(fun_caves.path.."/deco_rocks.lua") +--dofile(fun_caves.path.."/deco_fungal_tree.lua") +--dofile(fun_caves.path.."/deco_ferns.lua") +--dofile(fun_caves.path.."/deco_ferns_tree.lua") +--dofile(fun_caves.path.."/deco_water.lua") diff --git a/deco_caves.lua b/deco_caves.lua new file mode 100644 index 0000000..4fc8d95 --- /dev/null +++ b/deco_caves.lua @@ -0,0 +1,317 @@ +local node = fun_caves.node +local min_surface = -80 + +function fun_caves.decorate_cave(data, area, minp, y, ivm, biome_val_in) + local ivm_below = ivm - area.ystride + local ivm_above = ivm + area.ystride + local biome_val = biome_val_in + + ------------------- + local stone_type = node("default:stone") + local stone_depth = 1 + local air_count = 0 + + if y > -500 then + biome_val = biome_val / math.max(1, math.log(500 + y)) + end + ------------------- + --biome_val = 0.7 + ------------------- + if biome_val < -0.65 then + stone_type = node("default:ice") + stone_depth = 2 + elseif biome_val < -0.6 then + stone_type = node("fun_caves:thinice") + stone_depth = 2 + elseif biome_val < -0.5 then + stone_type = node("fun_caves:stone_with_lichen") + elseif biome_val < -0.3 then + stone_type = node("fun_caves:stone_with_moss") + elseif biome_val < -0.0 then + stone_type = node("fun_caves:stone_with_lichen") + elseif biome_val < 0.2 then + stone_type = node("fun_caves:stone_with_algae") + elseif biome_val < 0.35 then + stone_type = node("fun_caves:stone_with_salt") + stone_depth = 2 + if data[ivm] == node("default:stone") then + return stone_type + end + elseif biome_val < 0.5 then + stone_type = node("default:sand") + stone_depth = 2 + elseif biome_val < 0.6 then + stone_type = node("default:coalblock") + stone_depth = 2 + else + stone_type = node("fun_caves:hot_cobble") + end + -- "glow" + + local node_below + if y > minp.y then + node_below = data[ivm - area.ystride] + end + local node_above = data[ivm + area.ystride] + + local air_above = false + for i = 1, stone_depth do + if data[ivm + area.ystride * i] == node("air") then + air_above = true + end + end + + if data[ivm] == node("default:stone") and (stone_type == node("fun_caves:stone_with_algae") or stone_type == node("fun_caves:stone_with_lichen")) and node_above == node("air") and math.random(3) == 1 then + return node("dirt") + end + + if data[ivm] == node("default:stone") and air_above then + if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then + return node("fun_caves:radioactive_ore") + else + return stone_type + end + end + + local air_below = false + for i = 1, stone_depth do + if data[ivm - area.ystride * i] == node("air") then + air_below = true + end + end + + if data[ivm] == node("default:stone") and air_below then + if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then + return node("fun_caves:radioactive_ore") + else + return stone_type + end + end + + if node_below == node("air") and (data[ivm] == node("fun_caves:stone_with_lichen") or data[ivm] == node("fun_caves:stone_with_moss")) and math.random(50) == 1 then + return node("fun_caves:glowing_fungal_stone") + end + if node_above == node("air") and data[ivm] == node("fun_caves:stone_with_moss") and math.random(50) == 1 then + return node("fun_caves:glowing_fungal_stone") + end + + if data[ivm] == node("air") then + local sr = math.random(1000) + + -- hanging down + if node_above == node("default:stone") and sr < 80 then + if stone_type == node("default:ice") then + return node("fun_caves:icicle_down") + elseif stone_type == node("fun_caves:stone_with_algae") then + return node("fun_caves:stalactite_slimy") + elseif stone_type == node("fun_caves:stone_with_moss") then + return node("fun_caves:stalactite_mossy") + elseif stone_type == node("fun_caves:stone_with_lichen") then + return node("fun_caves:stalactite") + elseif stone_type == node("default:stone") then + return node("fun_caves:stalactite") + end + end + + -- fluids + --if y < min_surface and (node_below == node("default:stone") or node_below == node("fun_caves:hot_cobble")) and sr < 3 then + if y > minp.y and (node_below == node("default:stone") or node_below == node("fun_caves:hot_cobble")) and sr < 3 then + return node("default:lava_source") + elseif node_below == node("fun_caves:stone_with_moss") and sr < 3 then + return node("default:water_source") + -- standing up + elseif node_below == node("default:ice") and sr < 80 then + return node("fun_caves:icicle_up") + elseif node_below == node("fun_caves:stone_with_algae") and sr < 80 then + return node("fun_caves:stalagmite_slimy") + elseif node_below == node("fun_caves:stone_with_moss") and sr < 80 then + return node("fun_caves:stalagmite_mossy") + elseif node_below == node("fun_caves:stone_with_lichen") and sr < 80 then + return node("fun_caves:stalagmite") + elseif node_below == node("default:stone") and sr < 80 then + return node("fun_caves:stalagmite") + elseif node_below == node("fun_caves:hot_cobble") and sr < 80 then + if sr < 20 then + return node("fun_caves:hot_spike") + else + return node("fun_caves:hot_spike_"..math.ceil(sr / 20)) + end + elseif node_below == node("default:coalblock") and sr < 20 then + return node("fun_caves:constant_flame") + -- vegetation + elseif node_below == node("default:dirt") and (stone_type == node("fun_caves:stone_with_lichen") or stone_type == node("fun_caves:stone_with_algae")) and biome_val >= -0.5 then + if sr < 110 then + return node("flowers:mushroom_red") + elseif sr < 220 then + return node("flowers:mushroom_brown") + elseif node_above == node("air") and sr < 330 then + return node("fun_caves:giant_mushroom_stem") + elseif sr < 360 then + for i = 1, 12 do + local j = ivm + area.ystride * i + if j <= #data and data[j] == node("air") then + air_count = air_count + 1 + end + end + if air_count > 5 then + fun_caves.make_fungal_tree(data, area, ivm, math.random(2,math.min(air_count, 12)), node(fun_caves.fungal_tree_leaves[math.random(1,#fun_caves.fungal_tree_leaves)]), node("fun_caves:fungal_tree_fruit")) + --node_below = node("dirt") + end + end + elseif node_below == node("fun_caves:giant_mushroom_stem") and data[ivm - area.ystride * 2] == node("fun_caves:giant_mushroom_stem") then + return node("fun_caves:giant_mushroom_cap") + elseif node_below == node("fun_caves:giant_mushroom_stem") then + if node_above == node("air") and math.random(3) == 1 then + return node("fun_caves:giant_mushroom_stem") + else + return node("fun_caves:huge_mushroom_cap") + end + end + + if data[ivm] == node("air") then + air_count = air_count + 1 + end + end +end + +--function original_fun_caves_decorate_cave(data, area) +-- local ivm_below = ivm - area.ystride +-- local ivm_above = ivm + area.ystride +-- local dy = y - minp.y +-- +-- ------------------- +-- local stone_type = node("default:stone") +-- local stone_depth = 1 +-- local biome_val = biome_n[index3d] +-- if y > -500 then +-- biome_val = biome_val / math.max(1, math.log(500 + y)) +-- end +-- ------------------- +-- --biome_val = 0.7 +-- ------------------- +-- if biome_val < -0.6 then +-- if true then +-- stone_type = node("default:ice") +-- stone_depth = 2 +-- else +-- stone_type = node("fun_caves:thinice") +-- stone_depth = 2 +-- end +-- elseif biome_val < -0.5 then +-- stone_type = node("fun_caves:stone_with_lichen") +-- elseif biome_val < -0.3 then +-- stone_type = node("fun_caves:stone_with_moss") +-- elseif biome_val < -0.0 then +-- stone_type = node("fun_caves:stone_with_lichen") +-- elseif biome_val < 0.2 then +-- stone_type = node("fun_caves:stone_with_algae") +-- elseif biome_val < 0.35 then +-- stone_type = node("fun_caves:stone_with_salt") +-- stone_depth = 2 +-- if data[ivm] == node("default:stone") then +-- data[ivm] = stone_type +-- end +-- elseif biome_val < 0.5 then +-- stone_type = node("default:sand") +-- stone_depth = 2 +-- elseif biome_val < 0.6 then +-- stone_type = node("default:coalblock") +-- stone_depth = 2 +-- else +-- stone_type = node("fun_caves:hot_cobble") +-- end +-- -- "glow" +-- +-- if data[ivm] == node("air") then +-- -- Change stone per biome. +-- if data[ivm_below] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("air")) then +-- data[ivm_below] = stone_type +-- if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then +-- data[ivm_below - area.ystride] = node("fun_caves:radioactive_ore") +-- elseif stone_depth == 2 then +-- data[ivm_below - area.ystride] = stone_type +-- end +-- end +-- if data[ivm_above] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("air")) then +-- data[ivm_above] = stone_type +-- if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then +-- data[ivm_above - area.ystride] = node("fun_caves:radioactive_ore") +-- elseif stone_depth == 2 then +-- data[ivm_above + area.ystride] = stone_type +-- end +-- end +-- +-- if (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss")) and math.random(1,50) == 1 then +-- data[ivm_above] = node("fun_caves:glowing_fungal_stone") +-- end +-- +-- if data[ivm] == node("air") then +-- local sr = math.random(1,1000) +-- +-- -- fluids +-- if (data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:hot_cobble")) and sr < 3 then +-- data[ivm] = node("default:lava_source") +-- elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 3 then +-- data[ivm] = node("default:water_source") +-- -- hanging down +-- elseif data[ivm_above] == node("default:ice") and sr < 80 then +-- data[ivm] = node("fun_caves:icicle_down") +-- elseif (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss") or data[ivm_above] == node("fun_caves:stone_with_algae") or data[ivm_above] == node("default:stone")) and sr < 80 then +-- if data[ivm_above] == node("fun_caves:stone_with_algae") then +-- data[ivm] = node("fun_caves:stalactite_slimy") +-- elseif data[ivm_above] == node("fun_caves:stone_with_moss") then +-- data[ivm] = node("fun_caves:stalactite_mossy") +-- else +-- data[ivm] = node("fun_caves:stalactite") +-- end +-- -- standing up +-- elseif data[ivm_below] == node("fun_caves:hot_cobble") and sr < 20 then +-- if sr < 10 then +-- data[ivm] = node("fun_caves:hot_spike") +-- else +-- data[ivm] = node("fun_caves:hot_spike_"..(math.ceil(sr / 3) - 2)) +-- end +-- elseif data[ivm_below] == node("default:coalblock") and sr < 20 then +-- data[ivm] = node("fun_caves:constant_flame") +-- elseif data[ivm_below] == node("default:ice") and sr < 80 then +-- data[ivm] = node("fun_caves:icicle_up") +-- elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae") or data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:stone_with_moss")) and sr < 80 then +-- if data[ivm_below] == node("fun_caves:stone_with_algae") then +-- data[ivm] = node("fun_caves:stalagmite_slimy") +-- elseif data[ivm_below] == node("fun_caves:stone_with_moss") then +-- data[ivm] = node("fun_caves:stalagmite_mossy") +-- elseif data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("default:stone") then +-- data[ivm] = node("fun_caves:stalagmite") +-- end +-- elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 90 then +-- data[ivm_below] = node("fun_caves:glowing_fungal_stone") +-- -- vegetation +-- elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae")) and biome_val >= -0.5 then +-- if sr < 110 then +-- data[ivm] = node("flowers:mushroom_red") +-- elseif sr < 140 then +-- data[ivm] = node("flowers:mushroom_brown") +-- elseif air_count > 1 and sr < 160 then +-- data[ivm_above] = node("fun_caves:huge_mushroom_cap") +-- data[ivm] = node("fun_caves:giant_mushroom_stem") +-- elseif air_count > 2 and sr < 170 then +-- data[ivm + 2 * area.ystride] = node("fun_caves:giant_mushroom_cap") +-- data[ivm_above] = node("fun_caves:giant_mushroom_stem") +-- data[ivm] = node("fun_caves:giant_mushroom_stem") +-- elseif air_count > 5 and sr < 180 then +-- fun_caves.make_fungal_tree(data, area, ivm, math.random(2,math.min(air_count, 12)), node(fun_caves.fungal_tree_leaves[math.random(1,#fun_caves.fungal_tree_leaves)]), node("fun_caves:fungal_tree_fruit")) +-- data[ivm_below] = node("dirt") +-- elseif sr < 300 then +-- data[ivm_below] = node("dirt") +-- end +-- if data[ivm] ~= node("air") then +-- data[ivm_below] = node("dirt") +-- end +-- end +-- end +-- +-- if data[ivm] == node("air") then +-- air_count = air_count + 1 +-- end +-- end +--end diff --git a/deco_coral.lua b/deco_coral.lua new file mode 100644 index 0000000..7968ce3 --- /dev/null +++ b/deco_coral.lua @@ -0,0 +1,97 @@ + +minetest.register_node("fun_caves:pillar_coral", { + description = "Pillar Coral", + tiles = {"fun_caves_pillar_coral.png"}, + paramtype = "light", + light_source = 2, + groups = {cracky = 3, stone=1}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("fun_caves:brain_coral", { + description = "Brain Coral", + tiles = {"fun_caves_brain_coral.png"}, + light_source = 4, + groups = {cracky = 3, stone=1,}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("fun_caves:dragon_eye", { + description = "Dragon Eye", + tiles = {"fun_caves_dragon_eye.png"}, + light_source = 4, + groups = {cracky = 3, stone=1,}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("fun_caves:staghorn_coral", { + description = "Staghorn Coral", + drawtype = "plantlike", + tiles = {"fun_caves_staghorn_coral.png"}, + waving = false, + sunlight_propagates = true, + paramtype = "light", + light_source = 2, + walkable = false, + groups = {cracky = 3, stone=1, attached_node=1, sea=1}, + sounds = default.node_sound_stone_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + +function fun_caves.sea_plants() + if y >= light_depth and (data[index_3d] == node["sand"] or data[index_3d] == node["dirt"]) and (data[index_3d_above] == node["water_source"] or data[index_3d_above] == node["river_water_source"]) then + -- Check the biomes and plant water plants, if called for. + biome = valc.biome_ids[biomemap[index_2d]] + if y < water_level and data[index_3d_above + ystride] == node["water_source"] and table.contains(coral_biomes, biome) and n21[index_2d] < -0.1 and math_random(1,3) ~= 1 then + sr = math_random(1,100) + if sr < 4 then + data[index_3d_above] = node["brain_coral"] + elseif sr < 6 then + data[index_3d_above] = node["dragon_eye"] + elseif sr < 35 then + data[index_3d_above] = node["staghorn_coral"] + elseif sr < 100 then + data[index_3d_above] = node["pillar_coral"] + end + elseif surround then + for _, desc in pairs(valc.water_plants) do + placeable = false + + if not node_match_cache[desc] then + node_match_cache[desc] = {} + end + + if node_match_cache[desc][data[index_3d]] then + placeable = node_match_cache[desc][data[index_3d]] + else + -- This is a great way to match all node type strings + -- against a given node (or nodes). However, it's slow. + -- To speed it up, we cache the results for each plant + -- on each node, and avoid calling find_nodes every time. + pos, count = minetest.find_nodes_in_area({x=x,y=y,z=z}, {x=x,y=y,z=z}, desc.place_on) + if #pos > 0 then + placeable = true + end + node_match_cache[desc][data[index_3d]] = placeable + end + + if placeable and desc.fill_ratio and desc.content_id then + biome = valc.biome_ids[biomemap[index_2d]] + + if not desc.biomes or (biome and desc.biomes and table.contains(desc.biomes, biome)) then + if math_random() <= desc.fill_ratio then + data[index_3d] = desc.content_id + write = true + end + end + end + end + end + end +end diff --git a/fungal_tree.lua b/fungal_tree.lua index 8046351..3477cb4 100644 --- a/fungal_tree.lua +++ b/fungal_tree.lua @@ -12,19 +12,17 @@ colors[""] = "dye:white" fun_caves.fungal_tree_leaves = {} -- all leaves -function fun_caves.make_fungal_tree(data, area, pos, height, leaves, fruit) +function fun_caves.make_fungal_tree(data, area, ivm, height, leaves, fruit) for y = 0, height do local radius = 1 if y > 1 and y < height - 2 then radius = 2 end - local force_x = math.random(1,3) - 2 - local force_y = math.random(1,3) - 2 for z = -radius,radius do for x = -radius,radius do local sr = math.random(1,100) - local i = pos + z*area.zstride + y*area.ystride + x - if force_x == x and force_y == y then + local i = ivm + z*area.zstride + y*area.ystride + x + if x == 0 and y == 0 and z == 0 then data[i] = leaves elseif sr == 1 then data[i] = fruit diff --git a/init.lua b/init.lua index 6970fd4..71fc024 100644 --- a/init.lua +++ b/init.lua @@ -65,6 +65,7 @@ end dofile(fun_caves.path .. "/nodes.lua") +dofile(fun_caves.path .. "/deco.lua") dofile(fun_caves.path .. "/fungal_tree.lua") dofile(fun_caves.path .. "/mapgen.lua") dofile(fun_caves.path .. "/mobs.lua") diff --git a/mapgen.lua b/mapgen.lua index aff79d8..3c17190 100644 --- a/mapgen.lua +++ b/mapgen.lua @@ -8,86 +8,13 @@ local biome_noise = {offset = 0.0, scale = 1.0, spread = {x = 400, y = 400, z = local node = fun_caves.node ---local replaceable = {} ---for n, s in pairs(minetest.registered_nodes) do --- if s.is_ground_content and n ~= "air" then --- replaceable[node(n)] = true --- print(n) --- end ---end local min_surface = -80 +local coral_biomes = {"desert_ocean", "savanna_ocean", "rainforest_ocean", } local data = {} -local p2data = {} -- vm rotation data buffer -local lightmap = {} +--local p2data = {} -- vm rotation data buffer local vm, emin, emax, area, noise_area, csize -local div_sz_x, div_sz_z, minp, maxp, terrain, cave - -if fun_caves.world then - fun_caves.biomes = {} - local biomes = fun_caves.biomes - local biome_names = {} - biome_names["common"] = {} - biome_names["uncommon"] = {} - do - local biome_terrain_scale = {} - biome_terrain_scale["coniferous_forest"] = 0.75 - biome_terrain_scale["rainforest"] = 0.33 - biome_terrain_scale["underground"] = 1.5 - - local tree_biomes = {} - tree_biomes["deciduous_forest"] = {"deciduous_trees"} - tree_biomes["coniferous_forest"] = {"conifer_trees"} - tree_biomes["taiga"] = {"conifer_trees"} - tree_biomes["rainforest"] = {"jungle_trees"} - tree_biomes["rainforest_swamp"] = {"jungle_trees"} - tree_biomes["coniferous_forest"] = {"conifer_trees"} - tree_biomes["savanna"] = {"acacia_trees"} - - for i, obiome in pairs(minetest.registered_biomes) do - local biome = table.copy(obiome) - biome.special_tree_prob = 2 - if biome.name == "savanna" then - biome.special_tree_prob = 30 - end - local rarity = "common" - biome.terrain_scale = biome_terrain_scale[biome] or 0.5 - if string.find(biome.name, "ocean") then - biome.terrain_scale = 1 - rarity = "uncommon" - end - if string.find(biome.name, "swamp") then - biome.terrain_scale = 0.25 - rarity = "uncommon" - end - if string.find(biome.name, "beach") then - biome.terrain_scale = 0.25 - rarity = "uncommon" - end - if string.find(biome.name, "^underground$") then - biome.node_top = "default:stone" - rarity = "uncommon" - end - biome.special_trees = tree_biomes[biome.name] - biomes[biome.name] = biome - biome_names[rarity][#biome_names[rarity]+1] = biome.name - end - end - biomes["control"] = {} -end - -if false then - local cave_stones = { - "fun_caves:stone_with_moss", - "fun_caves:stone_with_lichen", - "fun_caves:stone_with_algae", - "fun_caves:stone_with_salt", - } - local mushroom_stones = {} - mushroom_stones[node("default:stone")] = true - mushroom_stones[node("fun_caves:stone_with_algae")] = true - mushroom_stones[node("fun_caves:stone_with_lichen")] = true -end +local minp, maxp local function place_schematic(pos, schem, center) local rot = math.random(4) - 1 @@ -157,15 +84,6 @@ local function get_decoration(biome) end -local function rangelim(x, y, z) - return math.max(math.min(x, z), y) -end - -local function getBiome(x, z) - return nil -end - - function fun_caves.generate(p_minp, p_maxp, seed) minp, maxp = p_minp, p_maxp vm, emin, emax = minetest.get_mapgen_object("voxelmanip") @@ -176,6 +94,24 @@ function fun_caves.generate(p_minp, p_maxp, seed) csize = vector.add(vector.subtract(maxp, minp), 1) noise_area = VoxelArea:new({MinEdge={x=0,y=0,z=0}, MaxEdge=vector.subtract(csize, 1)}) + -- There's a bug in the heightmap from valleys_c. Check for it. + local bullshit_heightmap = false + do + local j = -31000 + local k = 0 + for i = 1, #heightmap do + if j == heightmap[i] then + k = k + 1 + if k > (csize.x ^ 2) * 0.5 then + bullshit_heightmap = true + end + else + k = 0 + end + j = heightmap[i] + end + end + -- Deal with memory issues. This, of course, is supposed to be automatic. local mem = math.floor(collectgarbage("count")/1024) if mem > 300 then @@ -202,9 +138,9 @@ function fun_caves.generate(p_minp, p_maxp, seed) local ivm = area:index(x, minp.y, z) for y = minp.y, maxp.y do - if (y < min_surface or y < heightmap[index] - cave_3[index]) and cave_1[index3d] * cave_2[index3d] > 0.05 then + if (y < min_surface or bullshit_heightmap or y < heightmap[index] - cave_3[index]) and cave_1[index3d] * cave_2[index3d] > 0.05 then data[ivm] = node("air") - if y > min_surface and cave_3[index] < 1 and heightmap[index] == y then + if y > min_surface and cave_3[index] < 1 and heightmap[index] == y and not bullshit_heightmap then local ivm2 = ivm for y2 = y + 1, maxp.y + 8 do ivm2 = ivm2 + area.ystride @@ -228,160 +164,24 @@ function fun_caves.generate(p_minp, p_maxp, seed) for x = minp.x, maxp.x do index = index + 1 local dx = x - minp.x - index3d = noise_area:index(dx, csize.y - 1, dz) - local air_count = 0 - local ivm = area:index(x, maxp.y, z) + index3d = noise_area:index(dx, 0, dz) + local ivm = area:index(x, minp.y, z) - for y = maxp.y, minp.y, -1 do - if y < min_surface or y <= heightmap[index] - 20 then - local ivm_below = ivm - area.ystride - local ivm_above = ivm + area.ystride - local dy = y - minp.y - - ------------------- - local stone_type = node("default:stone") - local stone_depth = 1 - local biome_val = biome_n[index3d] - if y > -500 then - biome_val = biome_val / math.max(1, math.log(500 + y)) + for y = minp.y, maxp.y do + if y < min_surface or bullshit_heightmap or y <= heightmap[index] - 20 then + local i = fun_caves.decorate_cave(data, area, minp, y, ivm, biome_n[index3d]) + if i then + data[ivm] = i end - ------------------- - --biome_val = 0.7 - ------------------- - if biome_val < -0.6 then - if true then - stone_type = node("default:ice") - stone_depth = 2 - else - stone_type = node("fun_caves:thinice") - stone_depth = 2 - end - elseif biome_val < -0.5 then - stone_type = node("fun_caves:stone_with_lichen") - elseif biome_val < -0.3 then - stone_type = node("fun_caves:stone_with_moss") - elseif biome_val < -0.0 then - stone_type = node("fun_caves:stone_with_lichen") - elseif biome_val < 0.2 then - stone_type = node("fun_caves:stone_with_algae") - elseif biome_val < 0.35 then - stone_type = node("fun_caves:stone_with_salt") - stone_depth = 2 - if data[ivm] == node("default:stone") then - data[ivm] = stone_type - end - elseif biome_val < 0.5 then - stone_type = node("default:sand") - stone_depth = 2 - elseif biome_val < 0.6 then - stone_type = node("default:coalblock") - stone_depth = 2 - else - stone_type = node("fun_caves:hot_cobble") - end - -- "glow" - - if data[ivm] == node("air") then - -- Change stone per biome. - if data[ivm_below] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("fun_caves:stone_with_salt") and data[ivm_below] ~= node("air")) then - data[ivm_below] = stone_type - if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then - data[ivm_below - area.ystride] = node("fun_caves:radioactive_ore") - elseif stone_depth == 2 then - data[ivm_below - area.ystride] = stone_type - end - end - if data[ivm_above] == node("default:stone") or (stone_type == node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("fun_caves:stone_with_salt") and data[ivm_above] ~= node("air")) then - data[ivm_above] = stone_type - if stone_type == node("fun_caves:stone_with_salt") and math.random(500) == 1 then - data[ivm_above - area.ystride] = node("fun_caves:radioactive_ore") - elseif stone_depth == 2 then - data[ivm_above + area.ystride] = stone_type - end - end - - if (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss")) and math.random(1,50) == 1 then - data[ivm_above] = node("fun_caves:glowing_fungal_stone") - end - - if data[ivm] == node("air") then - local sr = math.random(1,1000) - - -- fluids - if (data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:hot_cobble")) and sr < 3 then - data[ivm] = node("default:lava_source") - elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 3 then - data[ivm] = node("default:water_source") - -- hanging down - elseif data[ivm_above] == node("default:ice") and sr < 80 then - data[ivm] = node("fun_caves:icicle_down") - elseif (data[ivm_above] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("fun_caves:stone_with_moss") or data[ivm_above] == node("fun_caves:stone_with_algae") or data[ivm_above] == node("default:stone")) and sr < 80 then - if data[ivm_above] == node("fun_caves:stone_with_algae") then - data[ivm] = node("fun_caves:stalactite_slimy") - elseif data[ivm_above] == node("fun_caves:stone_with_moss") then - data[ivm] = node("fun_caves:stalactite_mossy") - else - data[ivm] = node("fun_caves:stalactite") - end - -- standing up - elseif data[ivm_below] == node("fun_caves:hot_cobble") and sr < 20 then - if sr < 10 then - data[ivm] = node("fun_caves:hot_spike") - else - data[ivm] = node("fun_caves:hot_spike_"..(math.ceil(sr / 3) - 2)) - end - elseif data[ivm_below] == node("default:coalblock") and sr < 20 then - data[ivm] = node("fun_caves:constant_flame") - elseif data[ivm_below] == node("default:ice") and sr < 80 then - data[ivm] = node("fun_caves:icicle_up") - elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae") or data[ivm_below] == node("default:stone") or data[ivm_below] == node("fun_caves:stone_with_moss")) and sr < 80 then - if data[ivm_below] == node("fun_caves:stone_with_algae") then - data[ivm] = node("fun_caves:stalagmite_slimy") - elseif data[ivm_below] == node("fun_caves:stone_with_moss") then - data[ivm] = node("fun_caves:stalagmite_mossy") - elseif data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_above] == node("default:stone") then - data[ivm] = node("fun_caves:stalagmite") - end - elseif data[ivm_below] == node("fun_caves:stone_with_moss") and sr < 90 then - data[ivm_below] = node("fun_caves:glowing_fungal_stone") - -- vegetation - elseif (data[ivm_below] == node("fun_caves:stone_with_lichen") or data[ivm_below] == node("fun_caves:stone_with_algae")) and biome_val >= -0.5 then - if sr < 110 then - data[ivm] = node("flowers:mushroom_red") - elseif sr < 140 then - data[ivm] = node("flowers:mushroom_brown") - elseif air_count > 1 and sr < 160 then - data[ivm_above] = node("fun_caves:huge_mushroom_cap") - data[ivm] = node("fun_caves:giant_mushroom_stem") - elseif air_count > 2 and sr < 170 then - data[ivm + 2 * area.ystride] = node("fun_caves:giant_mushroom_cap") - data[ivm_above] = node("fun_caves:giant_mushroom_stem") - data[ivm] = node("fun_caves:giant_mushroom_stem") - elseif air_count > 5 and sr < 180 then - fun_caves.make_fungal_tree(data, area, ivm, math.random(2,math.min(air_count, 12)), node(fun_caves.fungal_tree_leaves[math.random(1,#fun_caves.fungal_tree_leaves)]), node("fun_caves:fungal_tree_fruit")) - data[ivm_below] = node("dirt") - elseif sr < 300 then - data[ivm_below] = node("dirt") - end - if data[ivm] ~= node("air") then - data[ivm_below] = node("dirt") - end - end - end - - if data[ivm] == node("air") then - air_count = air_count + 1 - end - end - elseif y < heightmap[index] then + elseif y < heightmap[index] and not bullshit_heightmap then local ivm_below = ivm - area.ystride if data[ivm] == node("air") and data[ivm_below] ~= node('air') then data[ivm_below] = node("dirt") end end - ivm = ivm - area.ystride - index3d = index3d - csize.x + ivm = ivm + area.ystride + index3d = index3d + csize.x end end end @@ -392,37 +192,10 @@ function fun_caves.generate(p_minp, p_maxp, seed) if DEBUG then vm:set_lighting({day = 15, night = 15}) else - vm:set_lighting({day = 0, night = 0}) vm:calc_lighting() end vm:update_liquids() vm:write_to_map() - vm, area, lightmap, terrain, cave = nil, nil, nil, nil, nil -end - -function fun_caves.respawn(player) - local pos = {x=0,y=0,z=0} - local cave_1 = minetest.get_perlin(cave_noise_1):get3d(pos) - local cave_2 = minetest.get_perlin(cave_noise_2):get3d(pos) - local biome_n = minetest.get_perlin(biome_noise):get3d({x=pos.x, y=pos.y, z=pos.z}) - local biome = biome_n - - while biome < -0.2 or biome > 0.0 do - pos.x = pos.x + math.random(20) - 10 - pos.z = pos.z + math.random(20) - 10 - - biome_n = minetest.get_perlin(biome_noise):get3d({x=pos.x, y=pos.y, z=pos.z}) - biome = biome_n - end - - while cave_1 * cave_2 <= 0.05 do - pos.y = pos.y + 1 - cave_1 = minetest.get_perlin(cave_noise_1):get3d(pos) - cave_2 = minetest.get_perlin(cave_noise_2):get3d(pos) - end - - pos.y = pos.y + 1 - player:setpos(pos) - return true -- Disable default player spawner + vm, area, noise_area = nil, nil, nil end